Skip to content

[Bug] TLS error message & documentation for API key auth #929

Open
@pearkes

Description

@pearkes

If you're using Temporal Cloud with API key authentication for a namespace:

$ tcld namespace auth-method get -namespace quickstart-jack.xxxxx
api_key

And connecting with Python:

TASK_QUEUE = os.environ.get("TASK_QUEUE", "tasks")
TEMPORAL_ADDRESS = os.environ.get("TEMPORAL_ADDRESS", "localhost:7233")
TEMPORAL_NAMESPACE = os.environ.get("TEMPORAL_NAMESPACE", "default")
TEMPORAL_API_KEY = os.environ.get("TEMPORAL_API_KEY", "")

async def main() -> None:
    client = await Client.connect(TEMPORAL_ADDRESS, namespace=TEMPORAL_NAMESPACE, api_key=TEMPORAL_API_KEY)
    executor = ThreadPoolExecutor()
    worker = Worker(
        client,
        task_queue=TASK_QUEUE,
        workflows=load_workflows(),
        activities=load_activities(),
        activity_executor=executor,
    )
    await worker.run()

This will raise this error:

$ poetry run python worker.py
Traceback (most recent call last):
  File "/Users/pearkes/code/jack/temporal/worker.py", line 75, in <module>
    asyncio.run(main())
    ~~~~~~~~~~~^^^^^^^^
  File "/Users/pearkes/.local/share/uv/python/cpython-3.13.2-macos-aarch64-none/lib/python3.13/asyncio/runners.py", line 195, in run
    return runner.run(main)
           ~~~~~~~~~~^^^^^^
  File "/Users/pearkes/.local/share/uv/python/cpython-3.13.2-macos-aarch64-none/lib/python3.13/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/Users/pearkes/.local/share/uv/python/cpython-3.13.2-macos-aarch64-none/lib/python3.13/asyncio/base_events.py", line 725, in run_until_complete
    return future.result()
           ~~~~~~~~~~~~~^^
  File "/Users/pearkes/code/jack/temporal/worker.py", line 62, in main
    client = await Client.connect(TEMPORAL_ADDRESS, namespace=TEMPORAL_NAMESPACE, api_key=TEMPORAL_API_KEY)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/pearkes/code/jack/temporal/.venv/lib/python3.13/site-packages/temporalio/client.py", line 177, in connect
    await temporalio.service.ServiceClient.connect(connect_config),                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/pearkes/code/jack/temporal/.venv/lib/python3.13/site-packages/temporalio/service.py", line 209, in connect
    return await _BridgeServiceClient.connect(config)                                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                       File "/Users/pearkes/code/jack/temporal/.venv/lib/python3.13/site-packages/temporalio/service.py", line 1212, in connect                                                                            await client._connected_client()
  File "/Users/pearkes/code/jack/temporal/.venv/lib/python3.13/site-packages/temporalio/service.py", line 1225, in _connected_client                                                                  self._bridge_client = await temporalio.bridge.client.Client.connect(
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<2 lines>...                                                                                           )                                                                                                         ^
  File "/Users/pearkes/code/jack/temporal/.venv/lib/python3.13/site-packages/temporalio/bridge/client.py", line 97, in connect                                                                        await temporalio.bridge.temporal_sdk_bridge.connect_client(                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        runtime._ref, config                                                                                      ^^^^^^^^^^^^^^^^^^^^
    ),                                                                                                        ^
RuntimeError: Failed client connect: `get_system_info` call error after connection: Status { code: Unknown, message: "transport error", source: Some(tonic::transport::Error(Transport, hyper::Error(Io, Kind(ConnectionReset)))) }
  1. Status { code: Unknown, message: "transport error" ... is quite inscrutable and could be considerably improved.
  2. You need to set TLS to True – this wasn't clear in the getting started docs, nor were API keys as an auth method mentioned. I found a reference to it in the Python client docs and figured that may be it.

This works:

TASK_QUEUE = os.environ.get("TASK_QUEUE", "tasks")
TEMPORAL_ADDRESS = os.environ.get("TEMPORAL_ADDRESS", "localhost:7233")
TEMPORAL_NAMESPACE = os.environ.get("TEMPORAL_NAMESPACE", "default")
TEMPORAL_API_KEY = os.environ.get("TEMPORAL_API_KEY", "")
TEMPORAL_TLS = bool(os.environ.get("TEMPORAL_TLS", False))

async def main() -> None:
    client = await Client.connect(TEMPORAL_ADDRESS, namespace=TEMPORAL_NAMESPACE, api_key=TEMPORAL_API_KEY, tls=TEMPORAL_TLS)
    # Use a thread pool executor for synchronous activities
    executor = ThreadPoolExecutor()
    worker = Worker(
        client,
        task_queue=TASK_QUEUE,
        workflows=load_workflows(),
        activities=load_activities(),
        activity_executor=executor,
    )
    await worker.run()

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions