Bug reportCompleted

Bug: Tailscale Remote Control fails with false-positive 'no MagicDNS name' error

Phuc Pham MinhPosted Shipped in 1.40.1

Bug Details

Summary
ServerCompass's new "Remote Control via Tailscale" feature (released today) fails with:

Tailscale HTTPS needs attention
Tailscale has no MagicDNS name on this machine. Enable MagicDNS in Tailscale, then try again.

This error is a false positive. MagicDNS and HTTPS Certificates are both confirmed enabled at the Tailscale account level, the device has a valid MagicDNS name, and manually running the exact operation ServerCompass performs (tailscale serve to publish an HTTPS *.ts.net URL) succeeds immediately with no errors.

Steps to Reproduce
Open ServerCompass → Dashboard → Remote Control tab
Select Tailscale as the connection method (vs. Local network / Cloudflare Tunnel)
Click "Use HTTPS (Safari)" or "Try again"
Error banner appears every time, blocking the feature entirely
Expected Behavior
ServerCompass should detect the existing, working MagicDNS + HTTPS Certificates configuration and successfully publish the tunnel (as tailscale serve itself does when run manually).

Actual Behavior
Persistent error blocking the feature, despite every underlying layer being verified healthy (see Evidence below). Restarting ServerCompass and fully quitting/relaunching Tailscale.app does not resolve it.

Evidence Collected
1. Tailscale Admin Console (authoritative account-level config)
Both settings confirmed enabled — buttons read "Disable MagicDNS..." and "Disable HTTPS..." (a "Disable" label only shows when the feature is currently ON):

MagicDNS: enabled
HTTPS Certificates: enabled
Tailnet DNS name: tail22c41b.ts.net
2. CLI status on the affected machine

Copy
$ tailscale status --json | jq '.Self.DNSName, .Self.Online'
"phms-macbook-pro.tail22c41b.ts.net."
true
Device has a valid, non-empty MagicDNS name and is online.

3. Manual reproduction of ServerCompass's own operation
Ran the exact underlying command ServerCompass documents itself as using ("Uses Tailscale Serve to publish a private https://*.ts.net URL"):

Copy
$ tailscale serve --bg --https=443 http://127.0.0.1:8787
Available within your tailnet:
https://phms-macbook-pro.tail22c41b.ts.net/
|-- proxy http://localhost:8787
Serve started and running in the background.
Succeeded immediately — no MagicDNS/HTTPS errors of any kind.

  1. End-to-end verification

Copy
$ curl -s -o /dev/null -w "%{http_code}" https://phms-macbook-pro.tail22c41b.ts.net/
200
The published HTTPS *.ts.net URL is live and reachable — full chain (MagicDNS → HTTPS cert issuance → Tailscale Serve) works correctly.

  1. Ruled out: stale app state — fully quit and relaunched both ServerCompass and Tailscale.app; error persisted identically.
  1. Ruled out: local route conflict — cleared all tailscale serve config (tailscale serve --https=443 off, confirmed via tailscale serve status → "No serve config") and retried in ServerCompass with a completely clean tunnel. Error persisted identically, ruling out any conflict with other services (e.g. a pre-existing serve route for an unrelated local dashboard on this machine).

Environment
macOS, Tailscale GUI app installed (/Applications/Tailscale.app, via System Extension io.tailscale.ipn.macsys)
A separate standalone tailscale CLI binary is also present at /usr/local/bin/tailscale (used for the diagnostic commands above)
Tailnet: tail22c41b.ts.net, device phms-macbook-pro (100.65.170.53)
Hypothesis for Root Cause (for your engineering team)
Given the disconnect between "OS-level Tailscale reports everything healthy" and "ServerCompass reports MagicDNS missing," the most likely explanations are:

Wrong Tailscale identity/socket queried. Two separate Tailscale integrations exist on this Mac: the sandboxed GUI app (System Extension io.tailscale.ipn.macsys) and a standalone CLI. If ServerCompass's detection code queries the LocalAPI via a different path/socket than the one actually holding the active MagicDNS state, it could read stale or empty data even though the "real" connection is healthy.
Race condition on check. The check may run before the LocalAPI has fully populated Self.DNSName after Tailscale reports "Connected," especially right after app launch.
Misattributed error message. The check may actually be catching a different failure (e.g. a tailscale serve invocation error unrelated to MagicDNS) and defaulting to a generic/wrong error string.
Unresolved Questions
Which exact Tailscale API/socket does ServerCompass query for Self.DNSName — the CLI (/usr/local/bin/tailscale) or the macsys System Extension socket directly?
Does ServerCompass cache the MagicDNS check result at app launch, or does "Try again" re-query live?

Reproducibility: Unknown · Impact: Minor issue

Environment

VERSION
unknown
OS
ARCH
CHANNEL

Resolution progress

SHIPPED · 1.40.1
  1. PENDING

  2. REVIEWING

  3. IN PROGRESS

  4. COMPLETED

  • Phuc Pham Minh submitted this request
  • Khoa Nguyen moved it to In progress
  • Khoa Nguyen moved it to Completed

Discussion1

Newest first
  • Phuc Pham Minh

    Confirmed root cause
    Server Compass 1.40.0 invokes:

    text
    Copy
    /Applications/Tailscale.app/Contents/MacOS/Tailscale status --json
    using Node execFile, without ensuring the child has a terminal-like environment.

    On macOS, the bundled Tailscale executable uses variables such as TERM, SHLVL, TERM_PROGRAM, and PS1 to decide whether to behave as the CLI or launch the GUI. This behavior is documented by Tailscale. Tailscale CLI documentation

    A controlled reproduction confirmed it:

    text
    Copy
    Normal terminal environment:
    exit=0, valid JSON, Self.DNSName present

    Terminal variables removed:
    exit=0
    stdout="The Tailscale GUI failed to start: ... Tailscale.CLIError error 3."
    Server Compass then follows this faulty sequence:

    Receives exit code 0 but non-JSON stdout.
    Silently rejects the output.
    Falls back to detecting only the 100.x network interface.
    That fallback contains the IP but no magicDnsName.
    It reports “Tailscale has no MagicDNS name.”
    tailscale serve is never attempted.
    This completely explains the false positive.

    Corrections to the original report
    Two details should be adjusted:

    /usr/local/bin/tailscale is not a separate Tailscale installation here. It is a shell wrapper pointing back to the same application binary:
    sh
    Copy
    #!/bin/sh
    /Applications/Tailscale.app/Contents/MacOS/tailscale "$@"
    Your manual Serve command proves the underlying stack works, but it is operationally equivalent rather than exact. Server Compass 1.40.0 actually runs approximately:
    sh
    Copy
    tailscale serve --bg --yes http://127.0.0.1:1867
    The internal server starts at port 1867, with fallback ports if occupied. Tailscale documents that Serve defaults to HTTPS and automatically provisions the TLS certificate. Tailscale Serve documentation

    Answers to your questions
    Which API/socket does Server Compass query?
    It does not query LocalAPI directly. It executes the bundled macOS Tailscale binary, which communicates with the active System Extension.

    Does “Try again” re-query live?
    Yes. It calls setSettings({mode: "tailscale"}), which reruns Tailscale detection. The result is not merely an app-launch cache. It fails repeatedly because each subprocess inherits the same non-terminal environment.

    Recommended engineering fix
    The minimal source fix is to force CLI mode for every bundled-Tailscale subprocess, for example:

    ts
    Copy
    execFile(file, args, {
    timeout: CLI_TIMEOUT_MS,
    maxBuffer: CLI_MAX_BUFFER,
    encoding: 'utf8',
    env: {
    ...process.env,
    TERM: process.env.TERM || 'dumb',
    },
    });
    Also recommended:

    Treat invalid JSON as a status-query failure, not “MagicDNS disabled.”
    Preserve sanitized exit code, stdout, and stderr in logs.
    Do not silently fall back from failed CLI detection to a misleading MagicDNS diagnosis.
    Test Finder-launched macOS environments with terminal variables absent.
    Trying /usr/local/bin/tailscale alone will not fix this machine because that wrapper reaches the same binary with the same inherited environment.
    The affected build is indeed the newly published v1.40.0 release. Server Compass v1.40.0 release

    Unresolved questions: none for root-cause identification; only vendor implementation and release timing remain.

Sign in to comment, vote and follow this request.

Sign in to reply