juanfont/headscale · error
creating pre-auth key
Error message
creating pre-auth key: %w
What it means
"creating pre-auth key: %w" at cmd/dev/main.go:184 wraps runHS(ctx, hsBin, configPath, "preauthkeys", "create", "-u", <userID>, "--reusable", "-e", "24h", "-o", "json") in cmd/dev. After creating the 'dev' user, the tool provisions a reusable pre-auth key valid for 24h. The wrapped error is a non-zero exit of that CLI invocation — the CLI's own stderr names the cause (bad user id, expiration rejected, DB failure).
Solutions
- Read the CLI error text above the wrapped message and fix the named flag/argument
- Ensure the whole run uses one scratch dir (don't reuse state across runs with -keep)
- Re-run `go run ./cmd/dev` from the current source so tool and CLI stay in sync
Defensive patterns
Strategy: try-catch
Try / catch
keyJSON, err := runHS(ctx, hsBin, configPath, "preauthkeys", "create", ...)
if err != nil {
// CLI stderr above names the refused flag/arg; ctx.Err() means interrupted
if ctx.Err() != nil {
return nil
}
return fmt.Errorf("creating pre-auth key: %w", err)
} Prevention
- Keep tool and CLI in one source tree to avoid flag drift
- Use a single scratch state dir per run
When it happens
Trigger: The userID extracted in the previous step not matching a DB row (e.g. user created in a different DB file because the state dir changed between calls); the CLI rejecting '-e 24h' or '--reusable' due to flag changes; ctx cancelled mid-run.
Common situations: Version skew between the compiled dev tool and the current CLI flags; state directory mutated between the users-create and preauthkeys-create steps.
Related errors
- creating user
- unmarshalling key JSON
- unmarshalling user JSON
- adding description to pre_auth_keys
- adding revoked to pre_auth_keys
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/d9b158a3892f03b4.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/dev/main.go:184
return fmt.Errorf("creating user: %w", err)
}
userID, err := extractUserID(userJSON)
if err != nil {
return fmt.Errorf("parsing user: %w", err)
}
// Create pre-auth key.
keyJSON, err := runHS(
ctx, hsBin, configPath,
"preauthkeys", "create",
"-u", strconv.FormatUint(userID, 10),
"--reusable",
"-e", "24h",
"-o", "json",
)
if err != nil {
return fmt.Errorf("creating pre-auth key: %w", err)
}
authKey, err := extractAuthKey(keyJSON)
if err != nil {
return fmt.Errorf("parsing pre-auth key: %w", err)
}
// Print banner.
fmt.Printf(
`
=== Headscale Dev Environment ===
Server: http://127.0.0.1:%d
Metrics: http://127.0.0.1:%d
Debug: http://127.0.0.1:%d/debug/ping
Config: %s
State: %s
Pre-auth key: %sView on GitHub (pinned to 565fd254d0)