juanfont/headscale · error · ErrInvalidAuthIDPrefix
auth ID has invalid prefix
Error message
auth ID has invalid prefix
What it means
ErrInvalidAuthIDPrefix is a sentinel error in hscontrol/types/common.go:27 returned by AuthID.Validate() (common.go:68-72) when an AuthID string does not start with the required 'hskey-authreq-' prefix (wrapped with the expected prefix in the message). Any parse via AuthIDOfString of a foreign or corrupted identifier hits it.
Source
Thrown at hscontrol/types/common.go:27
"runtime"
"strings"
"sync/atomic"
"time"
"tailscale.com/util/rands"
)
const (
SelfUpdateIdentifier = "self-update"
DatabasePostgres = "postgres"
DatabaseSqlite = "sqlite3"
)
// Common errors.
var (
ErrCannotParsePrefix = errors.New("cannot parse prefix")
ErrInvalidAuthIDLength = errors.New("auth ID has invalid length")
ErrInvalidAuthIDPrefix = errors.New("auth ID has invalid prefix")
)
const (
authIDPrefix = "hskey-authreq-"
authIDRandomLength = 24
// AuthIDLength is the total length of an AuthID: 14 (prefix) + 24 (random).
AuthIDLength = 38
)
type AuthID string
func NewAuthID() (AuthID, error) {
return AuthID(authIDPrefix + rands.HexString(authIDRandomLength)), nil
}
func MustAuthID() AuthID {
rid, err := NewAuthID()
if err != nil {View on GitHub (pinned to 565fd254d0)
Solutions
- Verify the value starts with 'hskey-authreq-' before/instead of parsing
- Pass the exact auth ID issued during registration, not another identifier
- Use AuthIDFromString and check errors.Is(err, ErrInvalidAuthIDPrefix) to reject early
- Return 400 to clients sending malformed auth IDs rather than 500
Example fix
// before
if !strings.HasPrefix(s, "oidc-") { ... }
// after
if _, err := types.AuthIDFromString(s); err != nil { return http.StatusBadRequest } Defensive patterns
Strategy: type-guard
Validate before calling
if !strings.HasPrefix(s, "hskey-authreq-") {
return errors.New("not an auth ID")
} Type guard
func isAuthID(s string) bool {
return strings.HasPrefix(s, "hskey-authreq-")
} Try / catch
if errors.Is(err, types.ErrInvalidAuthIDPrefix) { /* reject input as 400, do not retry */ } Prevention
- Do not feed arbitrary identifiers into AuthIDFromString
- Reject untrusted input failing the prefix check before any auth state lookup
When it happens
Trigger: Calling types.AuthIDFromString with arbitrary strings (node keys, session IDs, other prefixes); code passing the wrong URL parameter into the auth ID parser; refactors that switch which field is treated as the auth ID.
Common situations: Mixing up identifier types in registration callbacks; fuzzing or contract tests feeding generic strings; accepting auth IDs from untrusted input without prior format checks.
Related errors
- auth ID has invalid length
- failed to parse auth-key
- registration expired
- failed to parse ApiKey
- failed to parse oauth client secret
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/34cc5bdb6676cbcf.
Report an issue: GitHub.