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

  1. Open the exact SSH check URL the control plane issued, unmodified
  2. Copy URLs whole (quoting in shells) to avoid truncation
  3. 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

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


AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15). Data as JSON: /api/errors/eb0d6cc087f68ebc. Report an issue: GitHub.