[BUG] macOS Desktop client SSH remote connection floods server with SSH sessions, triggers MaxStartups throttling, never launches remote server

Status Fixed / completed
Reported on v2.1.101
Maintainer reply None cached
Activity 4 comments · opened Apr 15, 2026 · closed Apr 22, 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?

The Claude Desktop app (macOS) fails to establish SSH remote sessions to a Linux VPS. The connection hangs on "Connecting..." indefinitely, then fails with a generic "try again" prompt. No actionable error is shown in the client UI.

Root cause investigation revealed two compounding issues:

  1. SSH CONNECTION FLOODING: The Desktop client opens dozens of simultaneous SSH sessions to the remote server within seconds during connection setup. This triggers sshd's MaxStartups throttling, which drops connections — including the critical one needed to launch the remote server. The remote-server.log remains completely empty because the server binary never gets a chance to start.
  1. files.list RPC FLOODING: When connections do get through (after raising MaxStartups), the remote server's RPC handler issues hundreds of sequential files.list calls to enumerate the project directory tree before spawning ccd-cli. A project with ~25,000 files and ~990 directories generates 160+ files.list calls per connection phase, taking 5+ seconds per burst. Neither .gitignore, .claude/settings.json ignorePatterns, nor .claudeignore reduce this enumeration.

These issues did not occur with the previous Desktop client version. Terminal SSH to the same server works perfectly, and Claude Code CLI (v2.1.79) connects and operates without issue on the same VPS using the same user account.

What Should Happen?

The Desktop client should:

  1. Establish a single SSH connection (or a small, bounded number) to the remote server rather than flooding with dozens of simultaneous sessions.
  1. Respect .gitignore, .claudeignore, or .claude/settings.json ignorePatterns when performing the initial file tree enumeration via files.list RPC calls.
  1. Complete the SSH handshake and launch the remote server binary within a few seconds, presenting the user with an active Claude Code session — matching the behavior of the previous client version and the terminal CLI.
  1. Surface meaningful error messages in the UI when connection fails, rather than silently spinning on "Connecting..." with no diagnostic information.

Error Messages/Logs

=== journalctl -u sshd (showing connection flood + throttling) ===

Apr 14 21:41:27 sshd[1333]: error: beginning MaxStartups throttling
Apr 14 21:41:27 sshd[1333]: drop connection #19 from [CLIENT_IP]:60143 past MaxStartups
Apr 14 21:41:28 sshd-session: Accepted publickey for claudeuser from [CLIENT_IP] port 60125
Apr 14 21:41:28 sshd-session: session opened for user claudeuser
Apr 14 21:41:28 sshd-session: Accepted publickey for claudeuser from [CLIENT_IP] port 60127
Apr 14 21:41:28 sshd-session: Accepted publickey for claudeuser from [CLIENT_IP] port 60130
[... dozens more connections opened and closed within 1-2 seconds each ...]
Apr 14 21:41:57 sshd[1333]: exited MaxStartups throttling after 00:00:30, 18 connections dropped

=== remote-server.log (files.list flood when connections succeed) ===

2026/04/14 20:18:50 [Server] RPC request: method=files.list, id=17
2026/04/14 20:18:50 [Server] RPC response sent: id=17, hasError=false
2026/04/14 20:18:50 [Server] RPC request: method=files.list, id=18
[... 168 consecutive files.list calls from id=17 to id=185 in ~5 seconds ...]
2026/04/14 20:18:55 [Server] RPC response sent: id=185, hasError=false
2026/04/14 20:20:15 [Server] RPC request: method=process.spawn, id=186
[... ccd-cli spawns successfully after the flood completes ...]
[... then another burst of 185 files.list calls from id=189 to id=373 ...]
[... then another burst of 92 files.list calls from id=380 to id=471 ...]

=== After raising MaxStartups and truncating logs ===

remote-server.log remains EMPTY — the remote server binary is never launched.
The client-side connection still fails silently at "Connecting..."

=== Project stats ===

$ find /project/path -maxdepth 3 -type d | wc -l
989
$ find /project/path -type f | wc -l
25399
$ du -h --max-depth=1 /project/path
249M    frontend/        (242M is node_modules)
153M    node_modules/
118M    uploads/
16M     .git/

Steps to Reproduce

  1. Set up a Linux VPS with a non-root user account (e.g. "claudeuser") with:
  • SSH key-based authentication (ed25519)
  • Node.js installed via nvm
  • A project directory containing ~25,000+ files (typical Node.js project with node_modules, uploads, .git)
  1. Configure Claude Desktop (macOS) with an SSH remote connection to the non-root user account
  1. Click "Connect" in the Desktop client's Code tab
  1. Observe: Client shows "Connecting..." indefinitely, then fails
  1. Verify via journalctl -u sshd --since "5 minutes ago" on the server: dozens of SSH sessions are opened and closed rapidly, triggering MaxStartups throttling
  1. Verify via tail -f ~/.claude/remote/remote-server.log on the server: log remains empty (remote server never launches)
  1. For comparison, SSH into the same server as the same user and run claude from the terminal — it connects and operates normally

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

Desktop client version prior to the most recent update (exact version unknown). The remote server's ccd-cli binary is version 2.1.101, which was functioning with the previous Desktop client. CLI version 2.1.79 works correctly via terminal.

Claude Code Version

ccd-cli: 2.1.101 (remote server binary, installed by Desktop client) CLI: 2.1.79 (working via terminal as workaround) Desktop client: latest macOS version as of April 14, 2026

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

Re: Terminal/Shell - N/A — issue is with Desktop client's built-in SSH, not terminal usage. Terminal SSH (via macOS Terminal.app / bash) works correctly.

WORKAROUNDS ATTEMPTED (server-side):

  1. Added .claudeignore with node_modules/, uploads/, .git/, dist/, build/, *.log
  • Reduced directory count from 989 to 44
  • Did NOT reduce files.list RPC flood (server daemon ignores this file)
  1. Added .claude/settings.json with ignorePatterns
  • Also had no effect on the files.list enumeration
  1. Raised MaxStartups in sshd_config from 10:30:100 to 50:30:100
  • Eliminated throttling/dropped connections
  • But client still fails to launch the remote server
  1. Verified claudeuser environment: shell works, Node.js accessible, ccd-cli binary present and executable, ulimit -n adequate

SUCCESSFUL WORKAROUND:

Installed Claude Code CLI (v2.1.79) for the non-root user via npm install -g @anthropic-ai/claude-code@2.1.79 and authenticated via OAuth with Max subscription. Terminal-based Claude Code works perfectly on the same server with the same user account.

NOTE: CLI versions 2.1.80+ have a separate OAuth regression that prevents subscription-based authentication (redirect_uri mismatch / "Unknown scope" errors). Version 2.1.79 is the latest version with working OAuth for subscription accounts connecting to remote Linux servers.

RELATED ISSUES:

  • #37434 (SSH mode silently fails — --allow-dangerously-skip-permissions flag)
  • #36739 (Remote SSH connection fails after client update 1.1.7714)
  • #32734 (Timed out while waiting for handshake — internal ssh2 library)
  • #27165 (Desktop app gets stuck connecting via SSH)
  • #37747 (OAuth redirect_uri regression in 2.1.80+)

View original on GitHub ↗

4 Comments

github-actions[bot] · 6 months ago

Found 1 possible duplicate issue:

  1. https://github.com/anthropics/claude-code/issues/48523

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

ChimeEdu · 6 months ago

Follow-on Comment for GitHub Issue #48530

Copy everything below the line into the GitHub issue comment box.

---

Additional Diagnostic Steps — Client-Side Investigation

Following the original report, I conducted an exhaustive client-side investigation to rule out any remaining configuration or state issues. All server-side causes were already eliminated in the original report. This comment documents the additional steps taken to confirm this is a client binary issue.

1. Client-Side State Inspection

Inspected the Desktop client's local storage at ~/Library/Application Support/Claude/:

  • ssh_configs.json: Contained two SSH connection profiles — one correctly configured with an identity file path, and a second duplicate profile missing the sshIdentityFile field entirely. The trustedHosts array also contained a stale entry for a different user account that is no longer used for Claude Code connections.
  • claude-ssh-remote/: Contained cached remote connection state from the date of the initial failed connection attempts.
  • config.json: Reviewed for any SSH-relevant settings — nothing anomalous found.
  • No client-side known_hosts, .pem, or id_* key files were found in the Claude application support directory (the client uses the system SSH key path).

2. Client-Side State Cleanup

Performed a complete cleanup of potentially stale client state:

  • Deleted claude-ssh-remote/ directory entirely (cached remote state from failed attempts)
  • Rewrote ssh_configs.json to contain only the single correct SSH profile with the proper sshIdentityFile path, and removed stale entries from trustedHosts
  • Force-killed all Claude processes (killall "Claude" and killall "Claude Helper") to ensure no background processes retained stale state
  • Relaunched the Desktop client fresh

Result: Connection still hangs on "Connecting..." and fails. No change in behavior.

3. Server-Side Verification (Complete Summary)

For completeness, here is the full list of server-side verifications and fixes applied, none of which resolved the Desktop client connection issue:

| Check | Result |
|-------|--------|
| Non-root user account shell | ✅ Functional (echo, whoami succeed) |
| Node.js availability | ✅ Accessible via nvm (v22.21.1) |
| ccd-cli binary | ✅ Present and executable at ~/.claude/remote/ccd-cli/2.1.101 |
| Remote server binary | ✅ Present at ~/.claude/remote/server (5.6MB, executable) |
| SSH key authentication | ✅ ed25519 key auth works for both root and non-root user |
| ulimit -n (open files) | ✅ Adequate |
| MaxStartups in sshd_config | Raised from 10:30:100 to 50:30:100 — eliminated throttling but did not fix the issue |
| .claudeignore | Added to exclude node_modules/, uploads/, .git/, dist/, build/, *.log — reduced directory count from 989 to 44. Had no effect on the files.list RPC flood |
| .claude/settings.json with ignorePatterns | Added with same exclusions — also had no effect on enumeration |
| .gitignore | Already present with standard exclusions — not respected by the remote server's file listing RPC handler |
| Remote server log (remote-server.log) | Remains completely empty after clearing and reconnecting — confirms the remote server binary is never launched |
| journalctl -u sshd | Shows dozens of SSH sessions opening and closing within seconds, even after MaxStartups was raised |

4. Terminal CLI Verification

Installed Claude Code CLI (v2.1.79) for the non-root user via npm install -g @anthropic-ai/claude-code@2.1.79 and authenticated via OAuth with a Max subscription.

Terminal-based Claude Code works perfectly on the same server, same user account, same SSH key, same project directory. This conclusively demonstrates that:

  • The server environment is correctly configured
  • The non-root user account has all necessary permissions
  • The project directory is accessible and functional
  • Authentication with the Max subscription works
  • The ccd-cli / Claude Code runtime operates normally

The only path that fails is the Desktop client's built-in SSH remote connection.

5. API Outage vs. Desktop Client Bug (Disambiguation)

During this investigation, Anthropic experienced multiple API/auth outages (April 14–15, 2026). These caused separate API Error: 500 issues during active CLI sessions but are unrelated to the Desktop client SSH connection failure. The Desktop client fails at the SSH/remote-server launch layer — before any API call is ever made. The empty remote-server.log confirms this: the connection dies before the remote server binary starts, so no API communication is attempted.

6. Conclusion

Every server-side variable has been verified or corrected. Every client-side cache and configuration artifact has been cleared and rebuilt. The terminal CLI works flawlessly on the identical server environment. The Desktop client's SSH remote connection fails silently regardless of server-side configuration.

This is a client binary defect. The Desktop client's SSH connection handling (likely in the internal Node.js ssh2 library or the connection setup orchestration layer) is broken for remote VPS connections to non-trivial project directories.

Environment reminder:

  • Client: macOS (latest Claude Desktop, April 2026)
  • Server: Ubuntu Linux VPS
  • User: non-root dedicated account with SSH key auth (ed25519)
  • Project: ~25,000 files, ~990 directories (typical Node.js application with node_modules, uploads, .git)
  • Working workaround: Claude Code CLI v2.1.79 via terminal SSH
ChimeEdu · 5 months ago

Issue appears to have self-solved.

github-actions[bot] · 5 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.