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

  1. Re-copy the full URL emitted by 'headscale auth' or the SSH check flow, including auth_id
  2. Check templates/redirects that construct these URLs for parameter loss
  3. 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

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


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