juanfont/headscale · error

decoding ID token claims: %w

Error message

decoding ID token claims: %w

What it means

Error "decoding ID token claims: %w" thrown in juanfont/headscale.

Source

Thrown at hscontrol/oidc.go:284

		httpUserError(writer, NewHTTPError(http.StatusBadRequest, "nonce not found", err))
		return
	}

	if idToken.Nonce != nonce.Value {
		httpUserError(writer, NewHTTPError(http.StatusForbidden, "nonce did not match", nil))
		return
	}

	// The state/nonce cookies have served their CSRF purpose; clear them so a
	// single-use pair does not linger in the browser until MaxAge.
	clearOIDCCallbackCookie(writer, stateCookieName)
	clearOIDCCallbackCookie(writer, nonceCookieName)

	nodeExpiry := a.determineNodeExpiry(idToken.Expiry)

	var claims types.OIDCClaims
	if err := idToken.Claims(&claims); err != nil { //nolint:noinlineerr
		httpUserError(writer, fmt.Errorf("decoding ID token claims: %w", err))
		return
	}

	// Fetch user information (email, groups, name, etc) from the userinfo endpoint
	// https://openid.net/specs/openid-connect-core-1_0.html#UserInfo
	var userinfo *oidc.UserInfo

	userinfo, err = a.oidcProvider.UserInfo(req.Context(), oauth2.StaticTokenSource(oauth2Token))
	if err != nil {
		util.LogErr(err, "could not get userinfo; only using claims from id token")
	}

	// The [oidc.UserInfo] type only decodes some fields (Subject, Profile, Email, EmailVerified).
	// We are interested in other fields too (e.g. groups are required for allowedGroups) so we
	// decode into our own [types.OIDCUserInfo] type using the underlying claims struct.
	var userinfo2 types.OIDCUserInfo
	if userinfo != nil && userinfo.Claims(&userinfo2) == nil && userinfo2.Sub == claims.Sub {
		// Update the user with the userinfo claims (with id token claims as fallback).

View on GitHub (pinned to 565fd254d0)

Solutions

  1. Inspect the wrapped error for the underlying cause and correct the failing condition (decoding ID token claims); retry the operation after fixing the input, configuration, or environment.

Example fix

Inspect the wrapped error for the underlying cause and correct the failing condition (decoding ID token claims); retry the operation after fixing the input, configuration, or environment.

When it happens

Trigger: Thrown at hscontrol/oidc.go:284 when the library encounters an invalid state.

Common situations: The claims inside the OIDC ID token could not be decoded. Verify the identity provider returns a standard JWT ID token with the expected claims.


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