[BUG] Desktop SSH session: every API call fails with `OAuth authentication is currently not supported` (401) on `ccd-cli 2.1.121`

Resolved 💬 3 comments Opened Apr 30, 2026 by wspl Closed May 3, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Using Claude Code Desktop's SSH connection feature from a local macOS machine to a remote macOS machine, every prompt in the SSH session fails immediately with:

{
  "type": "error",
  "error": {
    "type": "authentication_error",
    "message": "OAuth authentication is currently not supported."
  },
  "request_id": "req_011C******************"
}

The remote ccd-cli (auto-deployed by Desktop at ~/.claude/remote/ccd-cli/2.1.121) is started and stdin is delivered correctly — the failure is specifically the API auth rejection when the remote process tries to make an inference call.

What makes this report distinct from existing ones:

  • Local Claude Desktop on the same machine, same OAuth login, works fine (no SSH).
  • A separately-installed standalone claude CLI on the remote machine works fine when run directly via a regular SSH terminal — that has its own OAuth token and is unaffected.
  • Only the Desktop → SSH → remote ccd-cli path fails. This is the OAuth credential that Desktop forwards into the remote ccd-cli process via the RPC channel.

In other words: same account, two working OAuth credentials in two other contexts, but the credential that Desktop hands to ccd-cli over SSH is rejected by the API.

What Should Happen?

The remote session uses the forwarded OAuth credential and responds normally, same as a local session.

Error Messages/Logs

Excerpt from ~/.claude/remote/remote-server.log on the remote, with usernames / hostnames / IDs redacted. The RPC transport layer is healthy — included to show that spawn and stdin delivery happen correctly:

[Server] RPC request: method=process.spawn, id=6
[shellenv] Extracted shell PATH (567 chars)
[process.Manager] Process <uuid> started, PID=<pid>,
  command=/Users/<user>/.claude/remote/ccd-cli/2.1.121
[Server] RPC response sent: id=6, hasError=false
[process.Manager] Starting stderr streaming for process <uuid>
[process.Manager] Starting stdout streaming for process <uuid>
 
[Server] RPC request: method=process.stdin, id=7
[process.Manager] WriteStdin called for process <uuid> with 854 bytes
[process.Manager] drainStdin <uuid>: 854 bytes,
  preview "{\"type\":\"control_request\",\"request\":{\"subtype\":\"initialize\",\"hooks\":{...}}}"
 
... (initialize / mcp_set_servers / get_context_usage all succeed) ...
 
[Server] RPC request: method=process.stdin, id=18
[process.Manager] WriteStdin called for process <uuid> with 26695 bytes
[Server] RPC response sent: id=18, hasError=false

All RPC responses are hasError=false. The 401 itself is not in remote-server.log because that log is only the RPC transport — the actual error is on ccd-cli's stderr, which Desktop streams back to the local app.

I can supply:

  • Full unredacted remote-server.log
  • Local Desktop App logs (the stderr stream from ccd-cli ends up there)
  • The full request_id for the 401

— privately if there is a preferred channel for that.

Steps to Reproduce

  1. Log in to Claude Code Desktop on the local Mac via the standard browser OAuth flow.
  2. Confirm Desktop works locally with no SSH (regular session, send any prompt — succeeds).
  3. In the environment dropdown, add an SSH connection to a remote macOS host (key-based auth).
  4. Start a session against that host and select any project folder.
  5. Send any prompt (e.g. hello).

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.1.119

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗