tailscale/tailscale · error
res.Error
Error message
res.Error
What it means
diskutilInfo runs `diskutil info -plist <id>` for each candidate disk that diskutil list reported and is not a boot disk; this error wraps a failed exec. Typical cause: the disk disappeared between list and info (USB/SD unplugged), or diskutil refused the identifier (invalid/ambiguous id, permissions).
Source
Thrown at client/local/local.go:754
// subject to change between releases.
func (lc *Client) SetComponentDebugLogging(ctx context.Context, component string, d time.Duration) error {
if !buildfeatures.HasDebug {
return feature.ErrUnavailable
}
body, err := lc.send(ctx, "POST",
fmt.Sprintf("/localapi/v0/component-debug-logging?component=%s&secs=%d",
url.QueryEscape(component), int64(d.Seconds())), 200, nil)
if err != nil {
return fmt.Errorf("error %w: %s", err, body)
}
var res struct {
Error string
}
if err := json.Unmarshal(body, &res); err != nil {
return err
}
if res.Error != "" {
return errors.New(res.Error)
}
return nil
}
// Status returns the Tailscale daemon's status.
func Status(ctx context.Context) (*ipnstate.Status, error) {
return defaultClient.Status(ctx)
}
// Status returns the Tailscale daemon's status.
//
// API maturity: this is considered a stable API.
func (lc *Client) Status(ctx context.Context) (*ipnstate.Status, error) {
return lc.status(ctx, "")
}
// StatusWithoutPeers returns the Tailscale daemon's status, without the peer info.
func StatusWithoutPeers(ctx context.Context) (*ipnstate.Status, error) {View on GitHub (pinned to cfe32b8be6)
Solutions
- Re-run the command with the device connected and stable; auto-detection re-lists disks each run.
- If the device keeps dropping, try another port/cable/reader, then verify with `diskutil list` run twice and comparing output.
- Pass an explicit stable target with `--disk /dev/diskN` once you've confirmed the id via `diskutil list`.
- If it persists, run `diskutil info -plist diskN` manually to see diskutil's stderr and rule out system-level disk errors (check Disk Utility / system log).
Example fix
// before: card removed mid-scan $ tailscale configure flash-appliance Error: diskutil info disk4: exit status 1 # disk4 vanished // after: reconnect, then re-run or be explicit $ diskutil list | grep external # confirm disk4 present $ tailscale configure flash-appliance --disk /dev/disk4
Defensive patterns
Strategy: retry
Validate before calling
// optional pre-check that the device still exists
if _, err := exec.Command("diskutil", "info", id).Output(); err != nil {
return fmt.Errorf("disk %s already gone; re-run discovery", id)
} Try / catch
// Go: retry transient disk-disappearance around diskutil info
var d diskCandidate
for attempt := 0; attempt < 3; attempt++ {
var err error
d, err = diskutilInfo(ctx, id)
if err == nil {
break
}
var ee *exec.ExitError
if !errors.As(err, &ee) {
return err // not a transient exec failure
}
time.Sleep(500 * time.Millisecond) // let USB re-enumerate
} Prevention
- Keep the target disk plugged and idle until flashing finishes.
- Re-run discovery right before each flash rather than caching disk ids.
- For flaky readers, use --disk with an id you've just re-confirmed via diskutil list.
When it happens
Trigger: During `tailscale configure flash-appliance` auto-detection: a removable drive listed by `diskutil list` is yanked out before `diskutil info` runs, causing ExitError; also seen when diskutil is missing from PATH or when the id handed to diskutil is stale.
Common situations: User unplugs the target USB/SD card mid-command; a flaky card reader dropping the device; disks changing while macOS re-enumerates (thunderbolt/USB hub renegotiation); running in environments where diskutil is restricted.
Related errors
AI-assisted analysis of tailscale/tailscale@cfe32b8be6 (2026-08-15).
Data as JSON: /api/errors/7ae5adaff8375b24.
Report an issue: GitHub.