microsoft / microsoft/vscode-remote-release
[Remote Tunnels] Tunnel process becomes zombie (silent, no relay reconnect) after all clients disconnect and Extension Host shuts down
@connor4312 is already working on this.
Since Mar 24, 2026.
- Dominant language
- Dockerfile
- Stars
- 4.2k
- Forks
- 469
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 1
Description
Summary
When all clients disconnect from a code tunnel (systemd user service), the reconnection grace period expires (default 3h), the Extension Host shuts down, and the relay WebSocket closes — the tunnel process does not attempt to re-establish the relay connection. It stays alive silently (no log output), and the tunnel appears offline on vscode.dev indefinitely. The only recovery is a full tunnel service uninstall + tunnel service install.
Environment
- VS Code CLI version:
1.112.0(commit07ff9d6178ede9a1bd12ad3399074d726ebe6e43) - OS: Ubuntu 24.04 LTS (Linux 6.17.0, x86_64)
- Deployment:
code tunnel service install→ systemd user service withRestart=always - Tunnel name: managed via
jpe1.rel.tunnels.api.visualstudio.com
Steps to Reproduce
- Run
code tunnel service installand connect from vscode.dev. - Close all browser/client connections to the tunnel.
- Wait for the ManagementConnection reconnection grace period to expire (3 hours).
- Observe the Extension Host shutdown:
Last EH closed, shutting down. - Check vscode.dev — tunnel shows offline.
- Check
systemctl --user status code-tunnel— process is still running (Active: running). - Check
journalctl --user -u code-tunnel— complete silence from this point on; no reconnection attempts, no errors.
Expected Behavior
After the relay WebSocket closes (due to all clients disconnecting / EH shutdown), the tunnel process should re-register with the relay and restore the "online" state, so new clients can connect without manual intervention.
Actual Behavior
The process enters a zombie state: alive (no exit, so Restart=always never triggers) but permanently disconnected from the relay. The tunnel remains offline on vscode.dev until the service is manually uninstalled and reinstalled.
Relevant Log Sequence
# Client disconnects, grace period starts
[07:48:11] [<unknown>][59b930de][ManagementConnection] The client has disconnected, will wait for reconnection 3h before disposing...
# 3h later — grace period expires
[10:48:19] [<unknown>][59b930de][ManagementConnection] The reconnection grace time of 3h has expired, so the connection will be disposed.
# Extension Host shuts down
[10:52:51] Last EH closed, shutting down
# ← Complete silence from this point. No relay reconnect attempt. Ever.
Note: immediately before the grace period started, a transient DNS failure was observed during a relay reconnect cycle:
[07:47:46] warn failed to check GitHub token: error sending request for url (https://api.github.com/user): error trying to connect: dns error: failed to lookup address information: Try again
This may have contributed to the relay WebSocket not being re-established properly, but the core issue is that the process never retries.
Workaround
A watchdog script (run via systemd timer every 5 minutes) that detects log silence > 10 minutes and calls systemctl --user restart code-tunnel. This works because --verbose mode produces continuous output (liveness pongs, etc.) when the relay is genuinely connected.
Additional Context
- The process is running as a systemd user service (
loginctl enable-lingeris set). - Two processes are spawned: a singleton server (long-lived) and a client wrapper that reconnects to it on respawn. After the EH shutdown, neither process attempts relay re-registration.
Restart=always/RestartSec=10in the service unit does not help because the process never exits.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.