bytebase/bytebase · error
subject mismatch: expected pattern %q, got %q
Error message
subject mismatch: expected pattern %q, got %q
What it means
ValidateToken in the WIF (workload identity federation) plugin rejects a token whose `sub` claim does not match the configured SubjectPattern regex. The pattern is an admin-defined allow-list for which federated identities may exchange tokens; a mismatch means the token's subject is outside that allow-list. The error message includes both the expected pattern and the actual subject for debugging.
Source
Thrown at backend/plugin/idp/wif/wif.go:69
claims.Expiry = registeredClaims.Expiry.Time().Unix()
}
if registeredClaims.IssuedAt != nil {
claims.IssuedAt = registeredClaims.IssuedAt.Time().Unix()
}
// Validate issuer
if claims.Issuer != config.IssuerUrl {
return nil, errors.Errorf("issuer mismatch: expected %q, got %q", config.IssuerUrl, claims.Issuer)
}
// Validate audience (skip if no allowed audiences configured)
if len(config.AllowedAudiences) > 0 && !validateAudience(claims.Audience, config.AllowedAudiences) {
return nil, errors.Errorf("audience mismatch: token has %v, allowed %v", claims.Audience, config.AllowedAudiences)
}
// Validate subject pattern
if !matchSubjectPattern(claims.Subject, config.SubjectPattern) {
return nil, errors.Errorf("subject mismatch: expected pattern %q, got %q", config.SubjectPattern, claims.Subject)
}
// Validate expiry
if time.Now().Unix() > claims.Expiry {
return nil, errors.New("token has expired")
}
return claims, nil
}
func validateAudience(tokenAudience []string, allowedAudiences []string) bool {
for _, allowed := range allowedAudiences {
for _, aud := range tokenAudience {
if aud == allowed {
return true
}
}
}View on GitHub (pinned to 1870550677)
Solutions
- Print/inspect the token's `sub` claim (decode the JWT payload) and compare against config.SubjectPattern.
- Update the WIF config SubjectPattern to match the legitimate subject format, or re-issue/obtain the token from the expected identity.
- Test the regex (e.g. Go regexp.MatchString) against the actual subject outside the service to confirm the pattern is correct.
- If the subject should never be restricted, clear/omit SubjectPattern so the check is skipped (matchSubjectPattern passes when pattern is empty).
Example fix
// before: pattern assumes GitHub Actions but token is from AWS config.SubjectPattern = `^repo:myorg/myapp:.*` // after: match the AWS ARN subject actually present in the token config.SubjectPattern = `^arn:aws:sts::123456789012:assumed-role/.+`
Defensive patterns
Strategy: validation
Validate before calling
import "regexp"
func subjectMatches(pattern, subject string) bool {
if pattern == "" { return true }
re, err := regexp.Compile(pattern)
return err == nil && re.MatchString(subject)
}
// call before ExchangeToken:
if !subjectMatches(cfg.SubjectPattern, claims.Subject) { /* surface error or fix pattern */ } Type guard
func hasValidSubject(tok *wif.Token, pattern string) bool {
return tok != nil && tok.Claims != nil && subjectMatches(pattern, tok.Claims.Subject)
} Prevention
- Unit-test SubjectPattern against real token subjects from each identity provider you federate.
- Log claims.Subject (not the full token) on failure to speed debugging.
- Prefer broad patterns initially, tighten gradually after confirming subject formats.
When it happens
Trigger: ExchangeToken -> ValidateToken is called with a WIF token whose claims.Subject fails matchSubjectPattern against config.SubjectPattern (non-nil pattern that does not regex-match the sub claim).
Common situations: Admin tightens the subject pattern after tokens were already issued; token comes from a different service account/identity than the pattern expects (e.g. pattern `^repo:org/app:.*` but token subject is `repo:org/other:ref`); pattern uses wrong regex syntax or wrong platform prefix (AWS ARN vs GCP service-account email); trailing/leading whitespace or casing differences in the sub claim.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- auth.sso.unsupported-provider-type
- auth.sso.no-authorization-endpoint
- Unauthenticated
- Internal
- Unauthenticated
AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06).
Data as JSON: /api/errors/7df7da41867f4741.
Report an issue: GitHub.