Symptoms
- Coder Desktop shows Connected and workspaces appear as running in the UI
-
ping6 <workspace>.coderfails with:getaddrinfo — nodename nor servname provided, or not known
-
dscacheutil -q host -a name <workspace>.coderreturns no results - Direct DNS queries to the Coder resolver (
dig @fd60:627a:a42b::53) returnNXDOMAINwith a root-server SOA instead of a Coder-generated address - SSH to
<workspace>.codermay still work if aProxyCommandfallback (Coder CLIssh --stdio) is configured, masking the DNS failure - The web terminal in the Coder dashboard works normally
- DNS resolution of <workspace.coder> hostnames was previously working and broke without any Coder configuration change
Root Cause
In the observed instance a third party network extension for a security product was intercepting all DNS traffic on the macOS host before it reached Coder Desktop's own network extension resolver. Although macOS's resolver configuration (scutil --dns) correctly directs .coder queries to the Coder resolver at fd60:627a:a42b::53 on the utun interface, the third party network extension was functioning as a transparent DNS proxy and capturing the packets at a lower level in the networking stack.
The intercepted query was then re-routed through the third party network extension's CGNAT address space (100.64.0.0/10) to an external DNS resolver that has no knowledge of the private .coder domain. The external resolver returns NXDOMAIN, and workspace name resolution fails.
Background: How Coder Desktop DNS Works on macOS
Coder Desktop creates a utun (user-space tunnel) interface and registers a supplemental DNS resolver scoped to the .coder domain via macOS's SystemConfiguration framework. When an application resolves a name ending in .coder, the system resolver routes the query over the tunnel to Coder's internal DNS server, which returns the workspace's IPv6 address within the Coder address space.
This mechanism relies on the macOS system resolver honouring the supplemental resolver configuration. Third-party network extensions (VPNs, security agents, DNS filters) that operate as transparent proxies can intercept packets before they reach the intended destination, bypassing the scoped resolver entirely.
Diagnosis
1. Confirm Coder Desktop is connected
Open Coder Desktop and verify that Coder Connect is enabled and at least one workspace is listed as running.
2. Test DNS resolution via the system resolver
Use dscacheutil, which exercises the macOS system resolver (unlike dig or nslookup, which query nameservers directly):
$ dscacheutil -q host -a name <workspace>.coder
name: <workspace>.coder
ipv6_address: fd60:627a:a42b:XXXX:XXXX:XXXX:XXXX:XXXXIf this returns no result, the system resolver is not reaching the Coder DNS server.
3. Test the Coder tunnel's diagnostic hostname
$ ping6 is.coder--connect--enabled--right--now.coderThis is a special hostname that the Coder resolver always answers. If this fails with a name resolution error, DNS is not reaching the Coder resolver.
4. Capture traffic on the tunnel interface
Identify the Coder utun interface from ifconfig or the scutil --dns output, then run:
$ sudo tcpdump -i utun5 port 53In a separate terminal, query the Coder resolver directly:
$ dig @fd60:627a:a42b::53 AAAA is.coder--connect--enabled--right--now.coderHealthy output — the tcpdump shows an IPv6 source address from the Coder address space:
IP6 fd60:627a:a42b:XXXX:XXXX:XXXX:XXXX:XXXX.62779 > fd60:627a:a42b::53.domain: ...Intercepted output — the tcpdump shows an IPv4 CGNAT source address and the query is sent to a non-Coder IP:
IP 100.64.0.1.63746 > 185.46.212.88.domain: 29229+ [1au] AAAA? is.coder--connect--...Additionally, the dig response will contain a root-server SOA record instead of a Coder-generated answer, confirming the query was leaked to the public internet:
;; AUTHORITY SECTION:
. 86398 IN SOA a.root-servers.net. nstld.verisign-grs.com. ...5. Confirm presence of third party network extension
$ systemextensionsctl list
* * PCBCQZJ7S7 com.zscaler.zscaler.TRPTunnel (...) TRPTunnel [activated enabled]The presence of an active Zscaler TRPTunnel extension combined with the CGNAT traffic pattern above confirms Zscaler DNS interception as the root cause.
6. Check STUN responses in Coder Desktop logs
$ log stream --predicate 'subsystem BEGINSWITH "com.coder.Coder-Desktop"' \
--level debugLook for STUN responses originating from IP addresses which do not correspond to the configured Coder DERP/STUN servers (see here for defaults). Running coder netcheck will also show the configured values for your Coder deployment. If the IP addresses displayed in the logs do not match the configured STUN server addresses then the requests are likely being intercepted.
Resolution
The fix requires a policy change in the third party network extension — it cannot be resolved from the Coder side alone.
Work with the organisation's administrator to create a bypass for .coder DNS traffic. Specifically:
-
Bypass
.coderdomain resolution — Configure the exclusion of DNS queries for the.codersuffix from transparent DNS interception so they are handled by the macOS system resolver and routed to the Coder Desktop tunnel. -
Optionally bypass Coder tunnel traffic entirely — If another system is also intercepting STUN and WireGuard traffic (evidenced by STUN responses from
136.226.0.0/16in the example above), exclude the Coderutuninterface or the Coder DERP relay addresses from inspection.
Share the following with the team to provide context:
- Coder Desktop documentation — overview of how Coder Desktop establishes its tunnel and DNS configuration
- The
scutil --dnsoutput showing the Coder supplemental resolver - The
tcpdumpanddigoutput from the diagnosis steps above demonstrating the interception
After the bypass is applied, disconnect and reconnect Coder Desktop. Verify resolution with:
$ dscacheutil -q host -a name <workspace>.coder
$ ping6 <workspace>.coderCommon Questions
Why does SSH still work even though DNS is broken?
If the Coder CLI is installed and the SSH config contains a ProxyCommand using coder ssh --stdio, SSH connections bypass Coder Desktop's DNS and tunnel entirely. The CLI connects to the Coder control plane over HTTPS and proxies the SSH session through the control plane's API. This path is unaffected by Zscaler's DNS interception.
Why does the web terminal work?
The web terminal runs inside the Coder dashboard, which communicates with the workspace agent through the Coder control plane over standard HTTPS. It does not depend on the local .coder DNS resolution or the Coder Desktop tunnel.
Could this also affect Tailscale or other utun-based tools?
Yes. Any tool that relies on macOS supplemental DNS resolvers bound to a utun interface may be affected if interception of DNS traffic is transparently performed. The diagnosis steps above can be adapted for other domains and tunnel interfaces.
Key Rule
Transparent DNS proxies (Zscaler, Cisco Umbrella, and similar security agents) can silently override macOS supplemental DNS resolver configurations. When Coder Desktop DNS resolution fails but the tunnel appears healthy, always check for third-party network extensions intercepting DNS traffic on the utun interface. The definitive test is tcpdump on the Coder tunnel interface: if DNS queries show an IPv4 CGNAT source address instead of an IPv6 Coder address, a transparent proxy is intercepting the traffic.