argoproj/argo-workflows · error

no claim found for key: %v

Error message

no claim found for key: %v

What it means

Claims.GetCustomGroup looks up the configured custom group claim key in RawClaim; when the key is absent from the token claims it returns this error. It surfaces during SSO callback when `customGroupClaimName` doesn't match any claim the IdP actually sent.

Source

Thrown at server/auth/types/claims.go:69

	err = json.Unmarshal(data, &localClaim.RawClaim)
	if err != nil {
		return err
	}

	if localClaim.RawClaim["email_verified"] == true || localClaim.RawClaim["email_verified"] == "true" {
		localClaim.EmailVerified = true
	}

	*c = Claims(localClaim)
	return nil
}

// GetCustomGroup is responsible for extracting groups based on the
// provided custom claim key
func (c *Claims) GetCustomGroup(customKeyName string) ([]string, error) {
	groups, ok := c.RawClaim[customKeyName]
	if !ok {
		return nil, fmt.Errorf("no claim found for key: %v", customKeyName)
	}

	sliceInterface, ok := groups.([]any)
	if !ok {
		return nil, fmt.Errorf("expected an array, got %v", groups)
	}

	newSlice := []string{}
	for _, a := range sliceInterface {
		val, ok := a.(string)
		if !ok {
			return nil, fmt.Errorf("group name %v was not a string", a)
		}
		newSlice = append(newSlice, val)
	}

	return newSlice, nil
}

View on GitHub (pinned to 35bff19146)

Solutions

  1. Set customGroupClaimName to the exact claim key present in the ID token (decode the token to inspect claims)
  2. Add the required scope (e.g. `groups`) to `sso.scopes` so the provider emits the claim
  3. Fix the claim mapping in the IdP (e.g. Dex connectors) to emit groups under the expected key
  4. Handle the error gracefully in UI/rbac mapping so users without the claim still get a default outcome if desired

Example fix

// before
sso:
  customGroupClaimName: groups   # IdP sends "memberOf"
// after
sso:
  customGroupClaimName: memberOf
Defensive patterns

Strategy: type-guard

Validate before calling

if _, ok := claims.RawClaim[customGroupClaimName]; !ok {
    // claim absent: skip group mapping or use default role
}

Type guard

func hasClaim(c *types.Claims, key string) bool {
    _, ok := c.RawClaim[key]
    return ok
}

Try / catch

groups, err := claims.GetCustomGroup(key)
if err != nil {
    log.Warnf("custom group claim %q missing: %v", key, err)
    groups = nil
}

Prevention

When it happens

Trigger: HandleCallback processes a login where the OIDC token has no claim with the key configured as `sso.customGroupClaimName` (typo in config, IdP not sending the claim, or the scope that includes it wasn't requested).

Common situations: Configuring `customGroupClaimName: groups` but the IdP names it `memberOf` or nests it; missing `groups`/`profile` scope in `sso.scopes`; provider omits claim for some users (no group memberships).

Related errors


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/b3794296ab9d168b. Report an issue: GitHub.