tailscale/tailscale · error
res.Status
Error message
res.Status
What it means
bootWholeDisks calls dfRootDevice to learn which device (e.g. "disk3s1s1") backs the root mount, and wraps its failure with this message. dfRootDevice fails when `df -P /` exits non-zero (the raw exec.Error/ExitError is returned unwrapped) or when its output cannot be parsed (see the "unexpected df output/line" errors).
Source
Thrown at client/local/local.go:490
return err
}
// TailDaemonLogs returns a stream the Tailscale daemon's logs as they arrive.
// Close the context to stop the stream.
//
// API maturity: this method is not considered a stable API and is
// subject to change between releases.
func (lc *Client) TailDaemonLogs(ctx context.Context) (io.Reader, error) {
req, err := http.NewRequestWithContext(ctx, "GET", "http://"+apitype.LocalAPIHost+"/localapi/v0/logtap", nil)
if err != nil {
return nil, err
}
res, err := lc.doLocalRequestNiceError(req)
if err != nil {
return nil, err
}
if res.StatusCode != 200 {
return nil, errors.New(res.Status)
}
return res.Body, nil
}
// EventBusGraph returns a graph of active publishers and subscribers in the eventbus
// as a [eventbus.DebugTopics].
//
// API maturity: this method is not considered a stable API and is
// subject to change between releases.
func (lc *Client) EventBusGraph(ctx context.Context) ([]byte, error) {
return lc.get200(ctx, "/localapi/v0/debug-bus-graph")
}
// EventBusQueues returns a JSON snapshot of event bus queue depths per client.
//
// API maturity: this method is not considered a stable API and is
// subject to change between releases.
func (lc *Client) EventBusQueues(ctx context.Context) ([]byte, error) {View on GitHub (pinned to cfe32b8be6)
Solutions
- Run `/bin/df -P /` yourself in that same context; if it errors, fix the environment (PATH, sandbox profile) that breaks it.
- Use absolute-system PATH: export PATH="/usr/bin:/bin:/usr/sbin:/sbin:$PATH".
- Bypass discovery with `--disk /dev/diskN`.
- If df works in Terminal but not under your launcher, launch the CLI from a normal Terminal session instead.
Example fix
// before $ sandbox-exec -p '(deny process-exec)' tailscale configure flash-appliance Error: locating root device: fork/exec /bin/df: Operation not permitted // after: allow exec or run unsandboxed $ tailscale configure flash-appliance # or explicit target: $ tailscale configure flash-appliance --disk /dev/disk4
Defensive patterns
Strategy: validation
Validate before calling
// verify df runs and yields a device before starting discovery
out, err := exec.Command("/bin/df", "-P", "/").Output()
if err != nil {
return fmt.Errorf("df -P / failed: %w", err)
}
lines := strings.Split(strings.TrimSpace(string(out)), "\n")
if len(lines) < 2 || !strings.HasPrefix(strings.Fields(lines[1])[0], "/dev/") {
return fmt.Errorf("df -P / output not usable: %q", out)
} Prevention
- Call the stock /bin/df by absolute path in wrappers and CI.
- Don't run the CLI under sandbox profiles that deny process-exec.
- In containers/VMs on macOS, prefer --disk since df output may not reflect real disks.
When it happens
Trigger: `df -P /` cannot execute (df not in PATH, permission denied) or exits non-zero (unknown filesystem error, df bug), while `tailscale configure flash-appliance` tries to exclude boot disks during macOS auto-detection.
Common situations: Sandboxed processes (Seatbelt profiles) denying exec of /bin/df; containers/VMs on macOS where the root mount confuses df; PATH manipulation replacing df; unusual fstab/auto_master setups making df error on '/'.
Related errors
AI-assisted analysis of tailscale/tailscale@cfe32b8be6 (2026-08-15).
Data as JSON: /api/errors/514d166ff175ed29.
Report an issue: GitHub.