Skip to content
Latchkey

Poetry Hangs or Fails on keyring in CI - Disable the Backend

On a headless runner, Poetry’s use of the keyring library tries to reach a system secret service that does not exist, so credential lookups error or hang. Disabling keyring makes Poetry read tokens from env/config instead.

What this error means

A poetry install/publish step errors with a keyring/SecretStorage failure (Failed to create the collection: Prompt dismissed), or silently hangs waiting on a D-Bus secret service. It only happens on CI where no desktop keyring is running.

poetry output
[keyring.errors.KeyringError]
Failed to create the collection: Prompt dismissed..
# or the job hangs on:
keyring.backends.SecretService ...

Diagnose it: which Python, and which index?

A pip failure in CI is usually about the interpreter or the index rather than the package. Runners have several Pythons installed, and the one on PATH is not necessarily the one your virtualenv or your workflow selected.

Terminal
which -a python python3 pip pip3
python -c "import sys; print(sys.executable, sys.version)"
pip config list
pip debug --verbose 2>/dev/null | grep -i "compatible tags" | head -5

Common causes

No keyring service on a headless runner

The keyring library defaults to a desktop secret service (SecretStorage/D-Bus, macOS Keychain). CI has none, so the backend errors or blocks.

Poetry tries keyring before env/config credentials

Unless told otherwise, Poetry consults keyring for index credentials, hitting the missing backend before falling back.

How to fix it

Disable keyring for the job

Point keyring at the null backend so Poetry uses env vars/config instead of a system service.

Terminal
export PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring
poetry config http-basic.pypi __token__ "$PYPI_TOKEN"
poetry install

Provide credentials via environment variables

Poetry reads index credentials from POETRY_HTTP_BASIC_* / POETRY_PYPI_TOKEN_*, avoiding keyring entirely.

Terminal
export POETRY_PYPI_TOKEN_PYPI="$PYPI_TOKEN"
# or for a named source "internal":
export POETRY_HTTP_BASIC_INTERNAL_USERNAME=__token__
export POETRY_HTTP_BASIC_INTERNAL_PASSWORD="$INTERNAL_TOKEN"

How to prevent it

  • Set PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring on headless CI.
  • Pass index credentials through env vars, not a keyring.
  • Keep credential config identical across local and CI to avoid surprises.

Frequently asked questions

What causes Poetry hangs or fails on keyring in CI?
There are 2 common causes: no keyring service on a headless runner and poetry tries keyring before env/config credentials. The keyring library defaults to a desktop secret service (SecretStorage/D-Bus, macOS Keychain).
How do I fix Poetry hangs or fails on keyring in CI?
There are 2 fixes depending on which cause you have: disable keyring for the job and provide credentials via environment variables. Work through them in order, since the first is the most common.
What does Poetry hangs or fails on keyring in CI actually mean?
A poetry install/publish step errors with a keyring/SecretStorage failure (Failed to create the collection: Prompt dismissed), or silently hangs waiting on a D-Bus secret service.
How do I stop Poetry hangs or fails on keyring in CI happening again?
Set PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring on headless CI. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card