From 043bebb7bc9ff5bc233ecf71238e2d68d04c16d2 Mon Sep 17 00:00:00 2001 From: "blinkagent[bot]" <237617714+blinkagent[bot]@users.noreply.github.com> Date: Fri, 14 Aug 2026 12:31:04 -0400 Subject: [PATCH] docs: add Coder Desktop stale-tunnel recovery and improve macOS log capture (#26735) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What Adds a **Recovering from a stale tunnel** section to the Coder Desktop user guide, with separate macOS and Windows procedures, and tightens the existing macOS log-collection instructions. ## Why Users in the field have hit a state where Coder Desktop's menu bar / tray shows **Coder Connect** as enabled but the embedded tunnel is no longer working: * `workspace.coder` fails to resolve (`No such host`), or * DNS returns stale `fd60:627a:a42b::/48` addresses that no longer route, causing `coder ssh`, file sync, and the directory picker to hang. Related issues: * coder/coder#26669 — `ExistsViaCoderConnect` false positives when Coder Desktop has stale DNS * coder/coder-desktop-windows#171 — Tray reports Coder Connect as healthy while tunnel/DNS is broken Until the underlying state-management gap is fixed in the apps, the docs should give users (and support) a safe, repeatable way to recover without rebooting. ## Changes `docs/user-guides/desktop/index.md`: 1. **New "Recovering from a stale tunnel" section** under Troubleshooting: * **macOS:** stop the VPN configuration with `scutil --nc stop`, quit the app via `osascript`, restart the helper daemon in place with `launchctl kickstart -k system/com.coder.Coder-Desktop.Helper`, flush DNS caches, then relaunch. * Includes a warning to **not** use `launchctl bootout`, which removes the daemon from launchd's system domain entirely and is not re-bootstrapped on app relaunch. * Includes a verification step using the built-in sentinel hostname `is.coder--connect--enabled--right--now.coder` (defined in `tailnet/conn.go` as `IsCoderConnectEnabledFmtString`) so users don't need a workspace name to confirm the tunnel is healthy. * Uses `dig @fd60:627a:a42b::53` (explicit server) and `dscacheutil -q host -a name` because plain `dig` does not respect the macOS system resolver. * **Windows:** stop the app and `Coder Desktop` service, flush DNS, restart, then verify the NRPT rule and Wintun adapter. Notes that `ipconfig /flushdns` does not reset the embedded resolver and that filtering agents (e.g., Zscaler) may still shadow `.coder` lookups. 2. **macOS log-collection improvements:** * Switch the predicate from `subsystem == "com.coder.Coder-Desktop"` to `subsystem BEGINSWITH "com.coder.Coder-Desktop"` so the export captures the app, helper daemon, and network extension (which all log under prefixed subsystems). * Add a `log stream` example for live tailing while reproducing an issue. ## Verification * `npx markdownlint-cli2 docs/user-guides/desktop/index.md` — 0 errors. * macOS recovery steps were validated end-to-end on a real install (the `kickstart -k` form, in particular, was confirmed to restart the helper without breaking the install, unlike `bootout`). --- Created on behalf of @mdanter --------- Co-authored-by: blink-so[bot] <211532188+blink-so[bot]@users.noreply.github.com> Co-authored-by: Atif Ali Co-authored-by: Nick Vigilante Co-authored-by: Matyas Danter --- docs/user-guides/desktop/index.md | 133 +++++++++++++++++++++++++++++- 1 file changed, 130 insertions(+), 3 deletions(-) diff --git a/docs/user-guides/desktop/index.md b/docs/user-guides/desktop/index.md index 7f4616918e..f576e7b984 100644 --- a/docs/user-guides/desktop/index.md +++ b/docs/user-guides/desktop/index.md @@ -169,7 +169,121 @@ You can also configure a `Updater:ForcedChannel` string value to lock users to a - Check system permissions for network extensions - Ensure only one copy of Coder Desktop is installed -### Collecting Logs +### Recover from a stale tunnel + +If the menu bar or tray shows **Coder Connect** as enabled but workspaces are +unreachable (SSH hangs, `workspace.coder` fails to resolve, or file sync cannot +list the workspace directory), the embedded tunnel may be in a stale state. +Restart the helper components first. +If that doesn't resolve the issue, reboot your computer. + +
+ +#### macOS + +Run the following commands in a terminal. +These steps leave the app and helper daemon installed. +They only restart the running tunnel and flush DNS caches. + +1. Stop the Coder VPN configuration: + + ```shell + vpn_name=$(scutil --nc list | grep "com.coder.Coder-Desktop" | awk -F'"' '{print $2}' | tail -n1) + if [ -n "$vpn_name" ]; then scutil --nc stop "$vpn_name"; fi + ``` + +2. Quit the Coder Desktop app: + + ```shell + osascript -e 'tell application id "com.coder.Coder-Desktop" to quit' + ``` + +3. Restart the helper daemon in place: + + ```shell + sudo launchctl kickstart -k system/com.coder.Coder-Desktop.Helper + ``` + + > [!WARNING] + > Do not use `launchctl bootout` here. `bootout` removes the daemon from + > launchd's system domain entirely, and relaunching the app does not + > re-bootstrap it. Use `kickstart -k` to restart it in place. + +4. Flush DNS caches: + + ```shell + sudo dscacheutil -flushcache + sudo killall -HUP mDNSResponder + ``` + +5. Confirm the stale tunnel is gone (the command should print nothing): + + ```shell + scutil --nc list | grep "com.coder.Coder-Desktop" + ``` + +6. Relaunch **Coder Desktop** from your `/Applications` folder and toggle **Coder Connect** back on. + +To verify the tunnel is healthy after relaunching, query the built-in sentinel +hostname against Coder Desktop's embedded DNS server: + +```shell +dig @fd60:627a:a42b::53 AAAA is.coder--connect--enabled--right--now.coder +short +dscacheutil -q host -a name is.coder--connect--enabled--right--now.coder +``` + +Both commands should return an `fd60:627a:a42b::/48` address. +If `dig` returns nothing or `dscacheutil` reports no entries, Coder Connect is not publishing DNS. +[Collect logs](#collect-logs) and file an issue. + +#### Windows + +Run the following in an **elevated PowerShell** session. +The service restart clears the embedded DNS state. +The NRPT and adapter checks confirm the system routing policy is intact. + +1. Stop the app and the VPN service: + + ```ps1 + Get-Process -Name "Coder Desktop" -ErrorAction SilentlyContinue | Stop-Process -Force + Stop-Service -Name "Coder Desktop" -Force + ``` + +2. Flush DNS caches: + + ```ps1 + ipconfig /flushdns + Clear-DnsClientCache + ``` + +3. Start the service again and relaunch the app: + + ```ps1 + Start-Service -Name "Coder Desktop" + Start-Process "C:\Program Files\Coder Desktop\CoderDesktop.exe" + ``` + +4. After re-enabling Coder Connect in the tray, verify the NRPT rule and the Wintun adapter exist: + + ```ps1 + Get-DnsClientNrptRule | Where-Object { $_.Namespace -like "*.coder" } + Get-NetAdapter | Where-Object { $_.InterfaceDescription -like "*Wintun*" } + ``` + + If either command returns nothing while Coder Connect shows as enabled, + the tunnel did not finish coming up. Disable and re-enable the toggle, or + repeat the steps above. + +> [!NOTE] +> `ipconfig /flushdns` does not reset Coder Desktop's embedded DNS resolver; +> restarting the service is what clears its internal cache. If you are running +> a network filtering agent (for example, Zscaler), it may shadow `.coder` +> lookups even after the tunnel comes back. Check with your IT team if DNS +> still fails after a clean restart. + +
+ +### Collect logs When reporting an issue, attach the relevant log files so we can diagnose it faster. @@ -182,11 +296,24 @@ Coder Desktop and its network extension write to the Apple [unified logging syst 1. Export the unified logs for the last hour with the `log` command: ```sh - log show --predicate 'subsystem == "com.coder.Coder-Desktop"' \ + log show --predicate 'subsystem BEGINSWITH "com.coder.Coder-Desktop"' \ --info --debug --last 1h > ~/Desktop/coder-desktop.log ``` - Adjust `--last` (e.g. `30m`, `2h`, `1d`) to cover the time the issue occurred. You can also view the same logs interactively in **Console.app** by filtering on the `com.coder.Coder-Desktop` subsystem. + The `BEGINSWITH` predicate captures the app, the helper daemon, and the + network extension, which all log under subsystems prefixed with + `com.coder.Coder-Desktop`. Adjust `--last` (e.g. `30m`, `2h`, `1d`) to + cover the time the issue occurred. + + You can stream the logs live while reproducing an issue: + + ```shell + log stream --predicate 'subsystem BEGINSWITH "com.coder.Coder-Desktop"' --info --debug + ``` + + You can also view the same logs interactively in **Console.app** by + filtering on `subsystem:com.coder.Coder-Desktop` with Info and Debug + messages enabled. 2. If you're using file sync, also collect the Mutagen daemon log: