Skip to content

Dropped SSH sessions leave running shells, too many orphan shells block new SSH sessions #4946

Open

Description

@aubwang

User Story

I use OpenShell to run a long lived coding sandbox on my server, which I SSH into via the Codex app's SSH Connections feature and Claude Code's equivalent.

On 26 October I noticed that my Codex wasn't able to connect at all into my Openshell environment (red light, "SSH connection failed" error message in Codex). After investigating I found 62 leftover shell processes in Openshell, which lined up with the Claude desktop app's attempts to reconnect after my Mac woke up from sleep. After terminating the 62 orphaned processes, my Codex application was able to connect to the Openshell environment right away.

Problem Statement

When an SSH connection to a sandbox ends without closing its channels (the client is killed, or the (client) computer goes to sleep, etc) the processes that were started for those channels can keep running. They stay owned by the sandbox server with no client and a new SSH session does not reattach to them. In a test, an interactive PTY shell was still running a 1 minute after its client was killed.

As closing a channel normally does terminate its process (see channel_close in crates/openshell-supervisor-process/src/ssh.rs), I would expect that a connection drop would also terminate its process, but it does not.

Impact / Why This Matters

Without closing the process when the connection drops, clients will leave behind running shells when they disconnect (e.g. when the computer goes to sleep). After 3 days there were 62 stranded processes.

After that point, every new exec or shell request to the sandbox fails with the error "failed to start boundary exec". Existing connections keep working, but the only way to open a new connection is to manually kill the shells. Until then, the sandbox looks healthy but is unusable if you want to start a new session.

Acceptance Criteria

  • When an SSH connection ends without closing its channels, the processes started for its non-main channels are killed, as they are on channel close.
  • Repeatedly killing SSH clients mid-session doesn't build up leftover processes, and new exec and shell requests keep succeeding.
  • The reconnectable main session still survives a dropped connection and can be reattached.

Reproduction Steps

  1. Create a sandbox (run openshell sandbox create)
  2. From a remote computer, connect to the sandbox with a PTY through the Openshell SSH proxy by running ssh -tt <sandbox>
  3. Open another terminal on the remote computer client, and kill that ssh client without exiting the shell by kill -9 <pid of the local ssh process>
  4. Wait until the supervisor logs "ssh relay closed" for that connection
  5. Check that PID from a new session ssh <sandbox> 'ps -o pid,ppid,etimes,stat,args -p <PID>'

Expected: the shell is gone, as after a clean exit or channel close.
Actual: it is still running, parent PID 1 (the sandbox server), with no client.

Suggested UX (if applicable)

No response

Environment

  • OpenShell: 0.1.5 (stock release binaries)
  • Gateway host: Ubuntu 26.04.1 LTS VM, kernel 7.0.0-38-generic, Docker 29.1.3
  • Deployment: standalone gateway as a systemd service, Docker compute driver, one sandbox
  • Access: OpenSSH client through openshell ssh-proxy as ProxyCommand
  • The connection-drop cleanup in ssh.rs is unchanged on main as of 2026-10-26

Logs

Activity

  1. added theissue type on Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    state:triage-neededOpened without agent diagnostics and needs triage

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions