juanfont/headscale · error
unmarshalling key JSON: %w (raw: %s)
Error message
unmarshalling key JSON: %w (raw: %s)
What it means
Returned by extractAuthKey in cmd/dev/main.go when json.Unmarshal fails on the output of 'headscale preauthkeys create'. The function expects JSON with a "key" field; non-JSON output (error text, help, empty) causes the unmarshal error, and the offending bytes are echoed in '(raw: ...)'.
Source
Thrown at cmd/dev/main.go:304
err := json.Unmarshal(data, &user)
if err != nil {
return 0, fmt.Errorf("unmarshalling user JSON: %w (raw: %s)", err, data)
}
return user.ID, nil
}
// extractAuthKey parses the JSON output of "preauthkeys create" and
// returns the key string.
func extractAuthKey(data []byte) (string, error) {
var key struct {
Key string `json:"key"`
}
err := json.Unmarshal(data, &key)
if err != nil {
return "", fmt.Errorf("unmarshalling key JSON: %w (raw: %s)", err, data)
}
if key.Key == "" {
return "", errEmptyAuthKey
}
return key.Key, nil
}
View on GitHub (pinned to 565fd254d0)
Solutions
- Inspect the '(raw: ...)' payload in the error to see the actual command output
- Run 'headscale preauthkeys create' by hand with the same arguments to surface the real failure
- Verify the user exists before creating the preauthkey ('headscale users list')
- Rebuild binaries so cmd/dev and the CLI agree on the output format
Example fix
// before
key, err := extractAuthKey(out)
// after
if err != nil {
return "", fmt.Errorf("preauthkeys create output not parseable (raw: %s): %w", out, err)
}
key, err := extractAuthKey(out) Defensive patterns
Strategy: validation
Validate before calling
if !json.Valid(out) {
return "", fmt.Errorf("preauthkeys create emitted non-JSON output: %s", out)
} Try / catch
if _, err := extractAuthKey(out); err != nil {
return fmt.Errorf("cannot proceed without auth key: %w", err)
} Prevention
- Create the user before creating preauthkeys in scripted flows
- Log raw CLI output at debug level in the dev tool for post-mortem
- Keep binary versions in lockstep
When it happens
Trigger: The dev tool runs 'headscale preauthkeys create --user ...' and pipes stdout to extractAuthKey. Fails when the command prints an error (e.g., nonexistent user, server unreachable, expired flags) or when the binary version emits a different output format.
Common situations: User referenced by the preauthkey command was not created earlier in the dev flow (step ordering bug); mismatched binary versions between cmd/dev and the headscale CLI; server error text going to stdout instead of stderr.
Related errors
- unmarshalling user JSON: %w (raw: %s)
- creating user: %w
- parsing user: %w
- creating pre-auth key: %w
- parsing pre-auth key: %w
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/19a02681aa934419.
Report an issue: GitHub.