Linux: repeated keyring unlock prompts during subagent spawn can stall session progress

Open 💬 3 comments Opened Feb 9, 2026 by DhruvDh
💡 Likely answer: A maintainer (etraut-openai, contributor) responded on this thread — see the highlighted reply below.

What version of Codex CLI is running?

codex-cli 0.98.0

What subscription do you have?

Pro

Which model were you using?

gpt-5.3-codex

What platform is your computer?

Linux 6.18.9-2-cachyos x86_64 unkown

What terminal emulator and version are you using (if applicable)?

Ghostty

What issue are you seeing?

On Linux, Codex CLI intermittently stalls during an active session when subagents are used, and I get a keyring unlock prompt (KeePassXC is my Secret Service backend). The stall lasts until I unlock the keyring, then the session continues. This is not deterministic, but in long sessions it happens multiple times (current session had 3+).

What steps can reproduce the bug?

Codex cli causes a system keyring unlock prompt reliably for me during MCP server initialization for the _first ever session in a new folder_.

I do not have a reliable reproduction for subagents causing system keyring unlock prompts. But details I can think of are:

  • session used --yolo
  • session was started in folder A, but work was being done in folder B. A session was never started in folder B, ever.
  • long running session with frequent subagent use. subagent spawns do not reliably cause system keyring unlock prompts.

What is the expected behavior?

  • no system keyring unlock prompts in the middle of sessions
  • ideally just one system keyring unlock prompt for the first time a unique mcp is initialized.

Additional information

_No response_

View original on GitHub ↗

3 Comments

DhruvDh · 6 months ago

I looked into this because I thought this should be a quick fix, but it's tricky.

Keyring reads on Linux go through Secret Service, so backend behavior there may amplify this, but I think regardless it is codex cli logic that makes the stall possible. Ideally, nothing outside of codex can stall codex.

Also, I found mcp_oauth_credentials_store = "file" which I did not test but could fix this for me; but regardless, that would be a security regression.

On startup, both parent sessions and subagent sessions go through the same Codex::spawn flow. That flow does two separate steps: it computes MCP auth status and then initializes MCP clients. For streamable-HTTP servers without a bearer-token env var, both steps load OAuth credentials, so the same server credentials can be read more than once per session startup. With repeated or concurrent subagent spawns, this multiplies credential-store reads; in auto and keyring modes those reads can hit Secret Service, and each blocking read can stall session progress until the keyring returns.

The two reads within a single spawn are sequential (auth-status first, then client init), so the primary fix is an in-process cache keyed by (server_name, url, store_mode) — the first read populates it, the second hits cache. Singleflight on top of that dedupes concurrent reads across simultaneous subagent spawns.

This reduces keyring reads, and reduces but does not eliminate the potential for mid-session stalls. Cache misses can still stall, which means what we really want is for any keyring access to be non-blocking/time-bound. So a timeout. But there is already a timeout! startup_timeout_sec applies after client construction, while OAuth credential load can happen before MCP initialize/list-tools. If timeout semantics are meant to protect startup progress, they should cover the full startup path including credential reads. One caveat: credential loads are synchronous today (oauth.rs:94, keyring-store/src/lib.rs:52), so bounding them requires offloading to spawn_blocking first. Then subagents can follow the same failure model as normal parent startup: if MCP auth/init for one server cannot complete in time, degrade that server and keep session progress moving.

If this sounds sensible, I can

  • open a PR for in-process token-load cache + singleflight in rmcp-client (auto/keyring), which should remove the repeated-read stall pattern during subagent startup.
  • and follow with PR2 to extend timeout coverage to pre-initialize credential reads (async-offloaded + bounded), so cold-miss keyring delays degrade that MCP server instead of blocking session progress.
DhruvDh · 6 months ago
  • alternatively, PR2 as a separate credential_load_timeout (or equivalent internal bound) is the least invasive way to cover the pre-initialize stall path. It avoids potentially broad “extend timeout” redesign.
etraut-openai contributor · 6 months ago

Thanks for the analysis. We don't have the bandwidth to review a PR at this time. If and when this issue bubbles up as a priority, we might take you up on that offer.