juanfont/headscale · warning · HTTPError
Invalid auth_id
Error message
Invalid auth_id
What it means
Returned by the SSH action follow-up handler when the auth_id string fails types.AuthIDFromString validation. The auth_id arrives as a URL parameter on the hold/check URL; anything that is not a valid opaque AuthID token (truncated, edited, injected) is rejected with 400.
Source
Thrown at hscontrol/noise.go:589
}
// sshActionFollowUp handles follow-up requests where the client
// provides an auth_id. It blocks until the auth session resolves or
// the request context is cancelled (e.g. the client disconnects).
func (ns *noiseServer) sshActionFollowUp(
ctx context.Context,
reqLog zerolog.Logger,
action *tailcfg.SSHAction,
authIDStr string,
srcNodeID, dstNodeID types.NodeID,
checkFound bool,
) (*tailcfg.SSHAction, error) {
authID, err := types.AuthIDFromString(authIDStr)
if err != nil {
return nil, NewHTTPError(
http.StatusBadRequest,
"Invalid auth_id",
fmt.Errorf("parsing auth_id: %w", err),
)
}
reqLog = reqLog.With().Str("auth_id", authID.String()).Logger()
auth, ok := ns.headscale.state.GetAuthCacheEntry(authID)
if !ok {
// The session is gone (expired, evicted, or lost on a control-plane
// restart). A bare error dead-ends the client: it keeps polling this
// now-defunct auth_id until the SSH connection times out. Re-delegate
// so a still-required check can complete instead.
if checkFound {
reqLog.Info().Caller().
Msg("SSH check auth session missing; re-delegating")
return ns.sshActionHoldAndDelegate(
reqLog, action, srcNodeID, dstNodeID,
)View on GitHub (pinned to 565fd254d0)
Solutions
- Open the exact SSH check URL the control plane issued, unmodified
- Copy URLs whole (quoting in shells) to avoid truncation
- Check reverse proxy handling of query string encoding
Defensive patterns
Strategy: type-guard
Type guard
func isValidAuthIDParam(s string) bool {
_, err := types.AuthIDFromString(s)
return err == nil
} Prevention
- Never hand-edit auth_id values in URLs
- Use clickable links or full clipboard copies of issued URLs
When it happens
Trigger: The user alters or truncates the SSH check URL in the browser; URL-encoding corruption through a reverse proxy; injection attempts against the follow-up endpoint.
Common situations: Browser or chat client wrapping/copying the URL badly; hand-typed URLs; a proxy re-encoding query parameters.
Related errors
- ErrSSHAuthSessionNotBound
- ssh action: cached auth session is not an SSH-check binding
- ssh action: cached binding does not match request src/dst
- tags in SSH source cannot access user-owned devices
- user destination requires source to contain only that same u
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/eb0d6cc087f68ebc.
Report an issue: GitHub.