codex mcp logout fails to remove fallback OAuth credentials when keyring deletion fails in auto mode
What version of Codex CLI is running?
codex-cli 0.135.0
What subscription do you have?
Not provided. The local CLI is using ChatGPT auth.
Which model were you using?
N/A. This is a CLI command issue (codex mcp logout).
What platform is your computer?
Linux 5.15.0-130-generic x86_64 x86_64
What terminal emulator and version are you using (if applicable)?
iTerm2 3.6.10 over SSH/tmux 3.4.
Codex doctor report
codex doctor --json was run. Relevant fields:
{
"overallStatus": "fail",
"codexVersion": "0.135.0",
"checks": {
"auth.credentials": {
"status": "ok",
"summary": "auth is configured",
"details": {
"auth storage mode": "File",
"stored ChatGPT tokens": "true",
"stored auth mode": "chatgpt"
}
},
"config.load": {
"status": "ok",
"details": {
"mcp servers": "2",
"model": "gpt-5.5"
}
},
"mcp.config": {
"status": "ok",
"summary": "MCP configuration is locally consistent",
"details": {
"configured servers": "2",
"stdio servers": "1",
"streamable_http servers": "1"
}
},
"network.provider_reachability": {
"status": "fail",
"summary": "one or more required provider endpoints are unreachable over HTTP"
},
"network.websocket_reachability": {
"status": "ok",
"summary": "Responses WebSocket handshake succeeded"
}
}
}
What issue are you seeing?
codex mcp logout <server> can fail before removing stale fallback OAuth credentials when MCP OAuth credential storage is in the default auto mode.
Observed command and error:
$ codex mcp logout linear
Error: failed to delete OAuth credentials: failed to delete OAuth tokens from keyring
In this case, the configured MCP server was a streamable HTTP server:
[mcp_servers.linear]
url = "https://mcp.linear.app/mcp"
The stale OAuth credentials were present in the fallback file storage (CODEX_HOME/.credentials.json), but the normal logout command failed while attempting keyring deletion and did not remove the fallback file entry.
What steps can reproduce the bug?
- Use the default MCP OAuth credential storage mode (
auto). - Have MCP OAuth credentials stored in the fallback file (
CODEX_HOME/.credentials.json). This can happen when keyring access is unavailable or when saving falls back to file storage. - Have keyring deletion fail for the same MCP credential key.
- Run:
codex mcp logout <server>
Actual result:
Error: failed to delete OAuth credentials: failed to delete OAuth tokens from keyring
The fallback file entry remains, so the next MCP startup can keep loading stale OAuth credentials.
A workaround is to force file mode for logout:
codex mcp -c 'mcp_oauth_credentials_store="file"' logout <server>
What is the expected behavior?
In auto mode, logout should attempt to remove credentials from every storage backend that may contain the credential.
If keyring deletion fails, Codex should still try to delete the fallback file entry from CODEX_HOME/.credentials.json. It may still warn/report the keyring deletion error, but it should not leave stale fallback credentials behind when file cleanup is possible.
Additional information
The behavior seems inconsistent with the load/save fallback semantics:
load_oauth_tokens_from_keyring_with_fallback_to_filefalls back to file when keyring lookup fails.save_oauth_tokens_with_keyring_with_fallback_to_filefalls back to file when keyring save fails.delete_oauth_tokens_from_keyring_and_filereturns early on keyring deletion error forOAuthCredentialsStoreMode::Auto, before callingdelete_oauth_tokens_from_file.
Relevant code path:
match store_mode {
OAuthCredentialsStoreMode::Auto | OAuthCredentialsStoreMode::Keyring => {
return Err(error.into_error())
.context("failed to delete OAuth tokens from keyring");
}
OAuthCredentialsStoreMode::File => false,
}
let file_removed = delete_oauth_tokens_from_file(&key)?;
This means Auto behaves like Keyring for delete errors, even though Auto behaves like keyring-with-file-fallback for load/save.