juanfont/headscale · warning · HTTPError
invalid auth id
Error message
invalid auth id
What it means
Thrown by authIDFromRequest when the auth_id URL parameter cannot be retrieved (stringParam fails, i.e. it is absent from the chi route context). This handler backs browser-based registration/SSH check flows where the auth_id links the browser session to a pending control-plane auth cache entry.
Source
Thrown at hscontrol/handlers.go:341
}
writer.Header().Set("Content-Type", "text/html; charset=utf-8")
writer.WriteHeader(http.StatusOK)
_, err = writer.Write([]byte(templates.AuthWeb(
"Authentication check",
"Run the command below in the headscale server to approve this authentication request:",
"headscale auth approve --auth-id "+authID.String(),
).Render()))
if err != nil {
log.Error().Err(err).Msg("failed to write auth response")
}
}
func authIDFromRequest(req *http.Request) (types.AuthID, error) {
raw, err := stringParam(req, "auth_id")
if err != nil {
return "", NewHTTPError(http.StatusBadRequest, "invalid auth id", fmt.Errorf("parsing auth_id from URL: %w", err))
}
// We need to make sure we dont open for XSS style injections, if the parameter that
// is passed as a key is not parsable/validated as a NodePublic key, then fail to render
// the template and log an error.
authId, err := types.AuthIDFromString(raw)
if err != nil {
return "", NewHTTPError(http.StatusBadRequest, "invalid auth id", fmt.Errorf("parsing auth_id from URL: %w", err))
}
return authId, nil
}
// RegisterHandler shows a simple message in the browser to point to the CLI
// Listens in /register/:registration_id.
//
// This is not part of the Tailscale control API, as we could send whatever URL
// in the [tailcfg.RegisterResponse.AuthURL] field.View on GitHub (pinned to 565fd254d0)
Solutions
- Re-copy the full URL emitted by 'headscale auth' or the SSH check flow, including auth_id
- Check templates/redirects that construct these URLs for parameter loss
- If it persists, verify the chi route pattern includes the expected parameter name
Defensive patterns
Strategy: validation
Validate before calling
if strings.TrimSpace(authIDRaw) == "" {
return errors.New("auth_id parameter is missing from URL")
} Prevention
- Always pass server-issued URLs through verbatim
- When building these URLs programmatically, assert every required parameter is set before rendering
When it happens
Trigger: A request to /register/ or /machine/ssh/action/ routed without the auth_id route parameter, or a hand-built URL that drops the query parameter.
Common situations: User manually truncates or retypes the registration URL from the CLI output; a template or redirect drops the auth_id parameter; route misconfiguration.
Related errors
- oidc state parameter is too short
- empty OIDC callback params
- registration expired
- auth ID has invalid length
- auth ID has invalid prefix
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/eda1c9eaffa47a93.
Report an issue: GitHub.