[Bug]: SSH environment added by ssh config alias breaks when the alias' port changes#7568

openedAug 19, 2026byGgt-ak8

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/desktop

Steps to reproduce

The alias here is the only stable way to reach the machine: its port is reassigned on every VM start, and the ssh config entry is kept current automatically.

  1. Create a VM reachable over SSH that gets assigned a high port on 127.0.0.1, with an entry added to ~/.ssh/config under an alias. The port changes on every VM start, the alias does not.
  2. Confirm the alias works from a terminal: ssh <alias> connects.
  3. In the desktop app, open Settings > Connections > Add environment > SSH.
  4. Fill in two fields only: the host alias, so no address has to be typed, and the username. Leave the port empty, since the alias already carries it.
  5. Connect. The environment is created and works normally.
  6. Note that the saved connection is now labelled SSH <user>@127.0.0.1:<port>, so the resolved address and port were captured instead of the alias.
  7. Restart the VM so it is assigned a different port. The ~/.ssh/config entry is updated accordingly. Change nothing in T3 Code.
  8. Confirm the alias still works from a terminal: ssh <alias> connects.
  9. Reconnect the saved environment in T3 Code.

Expected behavior

An environment added by alias keeps the alias as its address. Every connection attempt resolves the alias through the ssh config as it is at that moment, so a changed HostName or Port is picked up without touching T3 Code. A username typed by hand stays an override, because it was chosen deliberately.

Actual behavior

The alias is resolved once, when the environment is added, and the resolved host and port are persisted and reused. Step 9 fails: the connection is still aimed at the old port, even though ssh <alias> works from a terminal and the ssh config is correct. Nothing in the UI offers to go back to using the alias.

Impact

Major degradation or frequent failure

Version or commit

0.0.33

Environment

macOS, desktop app 0.0.33

Screenshots, recordings, or supporting files

Screenshot of the saved connection showing the captured address and port added in a comment below.

Workaround

Delete the saved connection and add it again with the same alias, on every port change.

Synced from GitHub

Small pointers from a shallow read, in case they save time:

  • The alias itself is stored, so nothing is lost. What breaks is that the target resolved from ssh -G at add time is persisted alongside it (packages/client-runtime/src/connection/onboarding.ts, prepareSshRegistration), and the stored port then takes precedence over the freshly resolved one on reconnect (packages/ssh/src/tunnel.ts, ensureEnvironment).
  • Because that stored port is passed explicitly to ssh as -p (packages/ssh/src/command.ts, baseSshArgs), it overrides the Port currently declared for the alias in the ssh config.
  • The saved target seems to have no way to distinguish a port the user typed from a port that was resolved automatically, which is likely why the snapshot is treated as an intentional override. The username does not have this problem, because it really was typed.
  • Worth checking as a side effect of any fix: the remote state key includes host and port (remoteStateKey), so making the port dynamic again could spawn a new remote state per port change instead of reusing the existing one.

Possibly related, none of them a duplicate: #3533 is the closest precedent, an ssh config directive not being honored. #6198 is a sibling, an SSH alias treated as a real address on another surface. #4144 and #5749 touch the same reconnect path for different reasons.

Note

This is an automated response from a bot acting on maria's behalf. This issue has had no activity since 2026-08-19. Is it still relevant on the current version? If so, your version and OS would help.

Synced from GitHub

A related variant that doesn't involve a port change at all: the target was an alias whose HostName is loopback and whose real endpoint comes from ProxyJump.

sshconfig
1Host wsl
2 HostName 127.0.0.1
3 Port 2222
4 ProxyJump pc
5 User seank

Adding an SSH environment/route as seank@wsl resolved the alias to its HostName and dialled 127.0.0.1 on the client — no jump, no port 2222 — so it failed with SshCommandError: Connection timed out during banner exchange. ssh wsl from a terminal was fine throughout.

Two things made this hard to read:

  • The failure is indistinguishable from a host-down error; nothing says the alias was partially resolved.
  • ssh -G wsl shows the correct port and jump, so a config-level check suggests everything is right.

Workaround on our side was to stop relying on the alias: HostName is now the address the endpoint actually listens on, with Port set and no ProxyJump. If alias resolution is meant to be supported for SSH targets, resolving only HostName while dropping Port/ProxyJump/HostKeyAlias is the part worth fixing, or at least warning about.

Same host also hits #5749 (systemd service vs. SSH launch race), but that is independent of this.

Synced from GitHub

Still happens on 0.1.1 (macOS, Lima VM whose ssh port changes on every start). Trace after a restart:

1ssh.environment.ensure.start {"alias":"lima-sandbox","hostname":"127.0.0.1","port":53791,...}
2ssh.tunnel.ready.failed ... ssh: connect to host 127.0.0.1 port 53791: Connection refused

The alias resolved to the new port, but the stored port still overrides it in ensureEnvironment. Deleting and re-adding the environment is still the only fix. Each re-add also leaves an orphaned ~/.t3/ssh-launch/<hash> dir on the remote, since the state key includes the port. My workaround for now is pinning Lima's ssh.localPort.

Written by Claude (Claude Code) on my behalf.