rancher/rancher · error
empty access token secret for user %s
Error message
empty access token secret for user %s
What it means
Thrown when the stored token secret for the user was found, but its trimmed string content is empty. The secret exists yet contains no credential, so it cannot be unmarshalled or used as a raw access token. This indicates a corrupt or half-written cache entry rather than a missing one.
Source
Thrown at pkg/auth/providers/keycloakoidc/keycloak_provider.go:209
if err != nil {
// If the secret lookup failed for a reason other than NotFound, surface the error.
if !apierrors.IsNotFound(err) {
return nil, fmt.Errorf("getting access token for user: %w", err)
}
// Secret not found: fall back to the access token stored in ProviderInfo.
accessToken, ok := token.GetProviderInfo()["access_token"]
if !ok || strings.TrimSpace(accessToken) == "" {
return nil, fmt.Errorf("no stored access token found for user %s", token.GetUserID())
}
oauthToken = &oauth2.Token{
AccessToken: strings.TrimSpace(accessToken),
}
} else {
// Secret retrieved successfully. First, try to interpret it as JSON-encoded oauth2.Token.
stored := strings.TrimSpace(storedOauthToken)
if stored == "" {
return nil, fmt.Errorf("empty access token secret for user %s", token.GetUserID())
}
if unmarshalErr := json.Unmarshal([]byte(stored), &oauthToken); unmarshalErr != nil || oauthToken == nil {
// If unmarshalling fails or yields nil, fall back to treating the secret as a raw access token string.
oauthToken = &oauth2.Token{
AccessToken: stored,
}
}
}
// Valid will return false if access token is expired
if !oauthToken.Valid() {
// since token is not valid, the TokenSource func used in the Client func will attempt to refresh the access token
// if the refresh token has not expired
logrus.Debugf("[generic oidc] RefreshAndUpdateToken: attempting to refresh access token")
}
reusedToken, err := oauth2.ReuseTokenSource(oauthToken, oauthConfig.TokenSource(ctx, oauthToken)).Token()
if err != nil {View on GitHub (pinned to 932558d4e6)
Solutions
- Delete the empty token secret so the code falls back to ProviderInfo['access_token'] or the user re-logs in
- Audit the writer path (UpdateToken/TokenMgr.SetSecret) that produced the empty value and guard it against persisting empty tokens
- Re-login the affected user to repopulate the cache
Example fix
// before
if stored == "" {
return nil, fmt.Errorf("empty access token secret for user %s", token.GetUserID())
}
// after: treat empty cache as a cache miss and fall through to the ProviderInfo fallback
if stored == "" {
accessToken, ok := token.GetProviderInfo()["access_token"]
if !ok || strings.TrimSpace(accessToken) == "" {
return nil, fmt.Errorf("no stored access token found for user %s", token.GetUserID())
}
oauthToken = &oauth2.Token{AccessToken: strings.TrimSpace(accessToken)}
} Defensive patterns
Strategy: validation
Validate before calling
// Before triggering refresh, check the cached secret is usable
stored, err := tokenMgr.GetSecret(userID, providerName, nil)
if err == nil && strings.TrimSpace(stored) == "" {
// Corrupt cache entry: drop it so the fallback path can run
_ = tokenMgr.DeleteSecret(userID, providerName)
} Prevention
- Never write a token secret without asserting the marshalled JSON is non-empty
- Treat an empty cached secret as a cache miss, not a hard failure, in wrapper code
- Alert on token secrets whose data length is zero
When it happens
Trigger: TokenMgr.GetSecret succeeds but returns "" (or only whitespace) for the user/authProvider key: a secret created with an empty string value, an UpdateToken call that persisted an empty token, or a manually edited/blanked secret.
Common situations: A previous token-update failed midway and wrote an empty value; someone manually recreated the secret without data; secret restored from backup with redacted content.
Related errors
- no stored access token found for user %s
- setting up reusable token: %w
- unmarshalling cached oauth token for provider %s: %w
- failed to fetch token: %w
- reusing the token source for provider %s: %w
AI-assisted analysis of rancher/rancher@932558d4e6 (2026-08-16).
Data as JSON: /api/errors/b60d2475288d3fd7.
Report an issue: GitHub.