juanfont/headscale · error
building headscale: %w
Error message
building headscale: %w
What it means
"building headscale: %w" at cmd/dev/main.go:138 wraps build.Run() of `go build -o <tmpDir>/headscale ./cmd/headscale` executed by cmd/dev. The tool compiles the real server binary into the scratch dir before serving; any compile error, missing toolchain, or write failure surfaces here. Stdout/stderr of the go build are already streamed to the console (build.Stdout/Stderr = os.Stdout/os.Stderr), so the actual compiler diagnostics appear above this error.
Source
Thrown at cmd/dev/main.go:138
if err != nil {
return fmt.Errorf("writing config: %w", err)
}
// Build headscale.
fmt.Println("Building headscale...")
hsBin := filepath.Join(tmpDir, "headscale")
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()
build := exec.CommandContext(ctx, "go", "build", "-o", hsBin, "./cmd/headscale")
build.Stdout = os.Stdout
build.Stderr = os.Stderr
err = build.Run()
if err != nil {
return fmt.Errorf("building headscale: %w", err)
}
// Start headscale serve.
fmt.Println("Starting headscale server...")
serve := exec.CommandContext(ctx, hsBin, "serve", "-c", configPath)
serve.Stdout = os.Stdout
serve.Stderr = os.Stderr
err = serve.Start()
if err != nil {
return fmt.Errorf("starting headscale: %w", err)
}
// Wait for server to be ready.
healthURL := fmt.Sprintf("http://127.0.0.1:%d/health", *port)
err = waitForHealth(ctx, healthURL, 30*time.Second)View on GitHub (pinned to 565fd254d0)
Solutions
- Read the compiler output printed before the error — fix the reported source lines first
- Enter the pinned toolchain: `nix develop` then re-run `go run ./cmd/dev`
- Verify `go version` >= 1.26.1 and `go build ./cmd/headscale` succeeds standalone
Example fix
# before system go # old toolchain, fails at go.mod's 1.26.1 minimum go run ./cmd/dev # after nix develop -c go run ./cmd/dev
Defensive patterns
Strategy: try-catch
Validate before calling
// verify the toolchain compiles before invoking the dev harness
build := exec.Command("go", "build", "./cmd/headscale")
if err := build.Run(); err != nil {
return fmt.Errorf("tree does not compile, fix first: %w", err)
} Try / catch
if err := build.Run(); err != nil {
// compiler diagnostics were already streamed; surface exit cause only
if ctx.Err() != nil {
return nil // interrupted build is an expected shutdown
}
return fmt.Errorf("building headscale: %w", err)
} Prevention
- Run `go build ./...` before `go run ./cmd/dev` on WIP trees
- Use `nix develop` for the pinned Go 1.26.1 toolchain
- Never run cmd/dev with GOOS/GOARCH overridden for another target
When it happens
Trigger: Running `go run ./cmd/dev` on a tree with compile errors; Go toolchain not installed or older than go.mod's 1.26.1 minimum; GOFLAGS/GOOS misconfigured so the binary is written for the wrong platform; read-only GOCACHE; no write access to the tmpDir.
Common situations: Pulling a branch mid-refactor; CI image with an older Go; a stale nix shell (AGENTS.md pins Go 1.26.1 via `nix develop`); GOFLAGS=-mod=vendor without a vendor dir.
Related errors
- creating temp dir: %w
- writing config: %w
- starting headscale: %w
- waiting for headscale: %w
- creating user: %w
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/d05e090580f975a6.
Report an issue: GitHub.