rancher/rancher · error

invalid token

Error message

invalid token

What it means

Defensive validity check after a successful golang-jwt Parse of the relay-state cookie. With golang-jwt, Parse already returns an error for invalid tokens, so token.Valid == false with err == nil is nearly unreachable in practice; this branch exists to guard against parser API changes or tokens that parse but carry no valid signature claim set. Hitting it means the library returned a token object it simultaneously refuses to vouch for.

Source

Thrown at pkg/auth/providers/saml/saml_client.go:662

	return nil
}

func (s *Provider) getUserIdFromRelayStateCookie(r *http.Request) (string, error) {
	userID := ""
	// The state is stored in a cookie, which has the relay state as the key and a JWT token containing the userID as the value
	if relayState := r.Form.Get("RelayState"); relayState != "" {
		relayStateCookie := s.clientState.GetState(r, relayState)
		jwtParser := newJWTParser()
		token, err := jwtParser.Parse(relayStateCookie, func(t *jwt.Token) (any, error) {
			secretBlock := x509.MarshalPKCS1PrivateKey(s.serviceProvider.Key)
			return secretBlock, nil
		})
		if err != nil {
			return "", fmt.Errorf("error parsing relay state token: %w", err)
		}
		if !token.Valid {
			return "", fmt.Errorf("invalid token")
		}
		claims := token.Claims.(jwt.MapClaims)
		userID, _ = claims[rancherUserID].(string)
	}

	return userID, nil
}

func newJWTParser() *jwt.Parser {
	return jwt.NewParser(jwt.WithValidMethods([]string{jwt.SigningMethodHS256.Name}))
}

func validateFinalRedirectURL(redirectURL string, rancherServerURL string) (string, error) {
	if redirectURL == "" {
		return "", errors.New("redirect URL was not provided")
	}
	parsed, err := url.Parse(redirectURL)
	if err != nil {

View on GitHub (pinned to 932558d4e6)

Solutions

  1. Treat exactly like a parse failure: discard the relay state and restart the SAML login flow
  2. Check the golang-jwt dependency version for behavior changes around token.Valid
  3. Capture and log the raw cookie value length/claims to identify how a parsed-but-invalid token was produced
Defensive patterns

Strategy: type-guard

Type guard

func isValidSignedState(token *jwt.Token, err error) bool {
    return err == nil && token != nil && token.Valid
}

Try / catch

token, err := jwtParser.Parse(relayStateCookie, keyFunc)
if err != nil || !token.Valid {
    return "", fmt.Errorf("relay state token rejected (err=%v valid=%v)", err, token != nil && token.Valid)
}

Prevention

When it happens

Trigger: A relay-state cookie that parses without error but whose internal validation flags were never set (custom parser configuration, future jwt library behavior changes); logically it follows error 480's Parse succeeding.

Common situations: Almost never seen in production; if reported, it usually indicates a golang-jwt version change or a hand-crafted cookie that trips an edge case in the parser rather than a normal misconfiguration.

Understand the failure class

Related errors


AI-assisted analysis of rancher/rancher@932558d4e6 (2026-08-16). Data as JSON: /api/errors/b1e348cd8960311d. Report an issue: GitHub.