juanfont/headscale · error
headscale exited: %w
Error message
headscale exited: %w
What it means
"headscale exited: %w" at cmd/dev/main.go:234 wraps serve.Wait() after the dev workflow finishes its setup and prints its banner. It fires when the spawned `headscale serve` process exits with a non-zero status for a reason other than Ctrl+C (ctx cancellation is checked first and returns nil). The child's stdout/stderr were forwarded, so the crash reason is already on the console.
Source
Thrown at cmd/dev/main.go:234
*port, metricsPort, metricsPort,
configPath, tmpDir,
authKey,
*port, authKey,
hsBin, configPath,
hsBin, configPath,
)
// Wait for headscale to exit.
err = serve.Wait()
if err != nil {
// Context cancellation is expected on Ctrl+C.
if ctx.Err() != nil {
fmt.Println("\nShutting down...")
return nil
}
return fmt.Errorf("headscale exited: %w", err)
}
return nil
}
// waitForHealth polls the health endpoint until it returns 200 or the
// timeout expires.
func waitForHealth(ctx context.Context, url string, timeout time.Duration) error {
deadline := time.Now().Add(timeout)
for time.Now().Before(deadline) {
if ctx.Err() != nil {
return ctx.Err()
}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return fmt.Errorf("creating request: %w", err)View on GitHub (pinned to 565fd254d0)
Solutions
- Scroll to the child's own panic/error output — the %w cause is usually just 'exit status 1/2'
- If a panic, fix the reported stack in hscontrol; re-run cmd/dev to reproduce
- If OOM/signal, free resources or stop whatever sent the signal, then re-run
Defensive patterns
Strategy: try-catch
Try / catch
if err := serve.Wait(); err != nil {
if ctx.Err() != nil {
return nil // Ctrl+C: expected shutdown, not an error
}
// child's panic/stack was already forwarded to stdout — read it there
return fmt.Errorf("headscale exited: %w", err)
} Prevention
- Check the forwarded child logs before assuming the harness is at fault
- Run the server under the dev tool when reproducing panics; it keeps logs on your console
When it happens
Trigger: The server crashing at runtime after a healthy start: fatal runtime error after a config reload, database corruption, panic in a handler, port conflict introduced mid-run, or SIGTERM from outside. Not returned for clean Ctrl+C shutdown.
Common situations: Server panics on a code path under development (this is a dev harness); OOM killer terminating the process; another service binding the same port after startup.
Related errors
- starting headscale: %w
- creating temp dir: %w
- writing config: %w
- building headscale: %w
- waiting for headscale: %w
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/dbca9d5f7c3da450.
Report an issue: GitHub.