Codex Desktop Windows SSH mobile availability fails with false expired session error

Open 💬 3 comments Opened Jul 8, 2026 by atlantho

What version of the Codex App are you using?

Codex Desktop for Windows with Codex CLI 0.143.0.

The SSH remote host also has Codex CLI 0.143.0 available from a login shell.

What platform is your computer?

Controller host:

Windows / x86_64
Codex Desktop using a WSL-backed runtime/engine

Remote host:

Linux / x86_64 over SSH

Mobile:

ChatGPT iOS app

What issue are you seeing?

Codex mobile remote control works for the Windows Codex Desktop host, but enabling mobile/signed-in-device access for an SSH connection fails with an incorrect session-expired error.

The SSH connection itself appears healthy:

  • The SSH remote is configured in Codex Desktop under Settings > Connections > SSH.
  • The SSH entry shows a green/connected status indicator.
  • The Desktop app can use the SSH connection.
  • The remote login shell can find codex, and codex --version reports 0.143.0.
  • ChatGPT iOS has been paired with Codex Desktop successfully.
  • Remote Control for the Windows Desktop host is enabled and works from the iPhone.

However, when trying to allow mobile/signed-in devices for the SSH connection, Codex Desktop shows this error:

Your Codex session on this device has expired. Sign in again and try again.

Signing out and signing back in to Codex Desktop does not fix it. The normal Codex Desktop session is clearly still valid: the Desktop app is signed in, chat works, and the iPhone pairing / Desktop remote control continues to work.

This makes the error look specific to the SSH remote-control availability path rather than a general expired login session.

Steps to reproduce

  1. On Windows, sign in to Codex Desktop.
  2. Pair ChatGPT iOS with Codex Desktop using the Codex mobile setup flow.
  3. Enable Remote Control / signed-in device access for the Windows Desktop host.
  4. Confirm the iPhone can control the Windows Desktop host.
  5. Add or discover an SSH host in Codex Desktop.
  6. Confirm the SSH host is reachable and appears connected/green in Settings > Connections > SSH.
  7. Click the mobile/signed-in-devices control for the SSH connection.
  8. Confirm the prompt to allow devices to control this SSH connection.

Observed:

Your Codex session on this device has expired. Sign in again and try again.

Expected:

The SSH connection should become available from signed-in/mobile devices, or the UI should show a specific actionable error if the SSH remote cannot be exposed.

Diagnostics already checked

  • Re-authenticating Codex Desktop did not resolve the SSH enablement error.
  • Re-pairing ChatGPT iOS with Codex Desktop succeeded and did not resolve the SSH enablement error.
  • The desktop remote-control feature flag is enabled locally.
  • The remote-control enrollment table for the Desktop host was checked while debugging the mobile pairing path.
  • The SSH remote itself is reachable and healthy from the Desktop side.
  • The failure is isolated to enabling mobile/signed-in-device access for the SSH connection.

Related issues checked

I searched existing openai/codex issues before filing. The closest issues I found are related, but none appear to describe this exact Windows Desktop + SSH availability toggle + false session-expired error:

  • #23699: SSH remote-control toggle/restart behavior with mobile, but the reported failure mode is different and macOS-based.
  • #23527: Mobile does not show SSH remote projects from a connected desktop host, but that is a project visibility issue after setup, not a failure to enable SSH availability.
  • #23466: Feature request/bug around inheriting desktop SSH hosts on mobile, related conceptually but not this session-expired error.
  • #23112: Stale local mobile pairing state can break Codex mobile setup, but in this case mobile pairing and Desktop remote control work.
  • #23915 and #22804: Remote-control authorization/account-id mismatch issues, related auth area but not this SSH availability toggle error.
  • #25080: Mobile cannot connect to a Linux SSH remote project on some Codex versions, but this issue fails earlier while enabling SSH access from signed-in devices.

I also searched for the exact text:

Your Codex session on this device has expired

and did not find an existing exact match.

Why this looks like a bug

The UI says the Codex session expired, but the same Desktop app session remains valid for normal Codex use and for mobile Remote Control of the Desktop host. The error appears to be thrown only by the SSH signed-in-device availability path.

The product should either reuse the valid Desktop/session state for this SSH availability action or surface the real underlying authorization/state error.

View original on GitHub ↗

3 Comments

atlantho · 1 month ago

Additional severity update: this is broader than the mobile SSH availability toggle.

I tested the same SSH host as a Codex Desktop SSH remote project. The underlying SSH and Git path works outside Codex Desktop:

ssh <ssh-alias> 'hostname; whoami; pwd; command -v codex; codex --version'
<hostname>
<remote-user>
/home/<remote-user>
/usr/local/bin/codex
codex-cli 0.143.0

The remote host can also reach GitHub and clone the repository successfully:

git clone https://github.com/<owner>/<repo> .
## main...origin/main

However, after opening that folder as an SSH remote project in Codex Desktop, even a minimal prompt fails before any useful work can run:

Your access token could not be refreshed because your refresh token was revoked. Please log out and sign in again.

This happens despite the Windows Codex Desktop app being freshly signed in and otherwise usable, and despite SSH/Git/Codex CLI on the remote host being healthy.

So the impact is more urgent than the original mobile toggle symptom:

  • SSH connectivity works.
  • The remote folder exists and contains a valid Git repository.
  • codex is available on the remote host.
  • But Codex Desktop cannot execute a basic prompt in the SSH remote project because the Desktop/remote-project auth path reports a revoked refresh token.

This blocks the SSH Remote Project workflow itself, not only mobile access to the SSH connection. In this Windows Desktop + WSL-backed runtime setup, it prevents using a core Codex Desktop remote-development capability.

Luan-Nguyen-659 · 23 hours ago

Additional data point: macOS -> macOS SSH host, codex 0.147/0.150, current app (Aug 2026)

Same class of failure as #31558 (and the coexistence problem from #23699), reproduced today on macOS:

Environment

  • Controller: Codex Desktop (macOS, current build) connected via SSH to an always-on macOS remote host.
  • Remote host: codex-cli 0.147.0 (~/.local/bin/codex); daemon-managed app-server self-updated to 0.150.1 (~/.codex/packages/standalone/current/codex).
  • Remote host CLI signed in via ChatGPT device auth (codex login status -> logged in). Remote host is normally an API-key/DeepSeek provider setup (preferred_auth_method="apikey", forced_login_method="api"); ChatGPT login required -c preferred_auth_method=chatgpt -c forced_login_method=chatgpt overrides.

What is healthy (verified via RUST_LOG foreground app-server + logs)

  • codex remote-control start -> daemon-managed codex app-server --remote-control --listen unix:// binds the control socket; remoteControlEnabled: true.
  • Remote control websocket connects: wss://chatgpt.com/backend-api/wham/remote/control/server, persisted enrollment (server_id=..., environment_id=env_..., account_id matches the controller's account), status reaches Connected ("waiting for enablement").
  • Desktop SSH proxy attaches to the daemon app-server (unix socket link verified).
  • codex remote-control pair on the remote host -> remoteControl/pairing/start failed: remote control pairing is unavailable until enrollment completes.

Failure that remains

  • Desktop Settings -> Connections -> SSH host -> "allow devices to control this connection" -> red toast: "Không thể cập nhật trạng thái khả dụng của thiết bị đã đăng nhập" (Unable to update signed-in device availability state). Availability toggle never sticks.
  • Whenever the daemon app-server is stopped/dies, the desktop's SSH bootstrap immediately respawns a plain codex -c features.code_mode_host=true app-server --listen unix:// (no --remote-control) which then wins the socket; the daemon start then reports "app server is running but is not managed by codex app-server daemon" / "connection is errored". With the daemon up, the desktop toggle RPC still errors.

This looks like the exact #23699 ownership/coexistence bug: the controller keeps a non-daemon-managed code-mode app-server in the picture, while enrollment/availability lives on the daemon-managed --remote-control app-server. Server-side state (login, enrollment, websocket) is all correct; the toggle failure is still controller/protocol-side. Happy to provide more logs/files if useful.

Luan-Nguyen-659 · 22 hours ago

Update: root cause found — forced_login_method = "api" blocks remote control (PermissionDenied)

Continuing from the comment above. Differential testing (working controller vs failing SSH host, same machine class) identified the exact cause:

The remote host's ~/.codex/config.toml contains:

preferred_auth_method = "apikey"
forced_login_method = "api"

(Remote host normally runs as an API-key / DeepSeek provider setup.)

With that config, the daemon-managed codex app-server --remote-control fails the wham websocket immediately and forever:

WARN codex_app_server_transport::transport::remote_control::websocket: failed to connect ...
  error=remote control requires ChatGPT authentication
  error_kind=PermissionDenied
  has_enrollment=false

It retries with backoff indefinitely, so remote-control start --json reports status: connecting / timedOut: true / "connection is errored", remote-control pair reports "pairing is unavailable until enrollment completes", and the desktop's signed-in-devices toggle shows the availability-update error.

After changing those two keys to "chatgpt" (ChatGPT login already present via device auth), the SAME app-server connects successfully without any CLI overrides:

remote control websocket status changed: Connecting -> Connected
connected to app-server remote control websocket (server_id=..., environment_id=...)
has_enrollment=true

and codex remote-control start --json reports status: connected / timedOut: false, codex remote-control pair returns a pairing code.

So: remote-control requires ChatGPT auth; a host configured preferred_auth_method="apikey" / forced_login_method="api" for its normal model provider will silently fail every remote-control path (websocket, pair, desktop signed-in-devices availability). It would help if the remote-control paths surfaced this PermissionDenied (e.g., "remote control requires ChatGPT authentication") in the desktop UI instead of the generic availability/expired-session errors, and if remote-control start/pair reported the real auth-mode conflict. Model provider (DeepSeek) is unaffected by flipping the auth methods.