rancher/rancher · error
error validating ttl against default and max: %w
Error message
error validating ttl against default and max: %w
What it means
Raised in Manager.createDerivedToken (pkg/auth/tokens/manager.go:108) when exttokenstore.IngestTTL fails while validating the requested token TTL. IngestTTL never rejects the request's own ttlMillis (0 means default, negative means infinite; both are clamped) — the only failure path is ParseTTLToMilliseconds erroring on the server settings auth-token-max-ttl-minutes or auth-token-default-ttl-minutes, whose values must be plain integer strings ('600', not '600m', '10h', or 'abc'). The handler converts this to HTTP 500.
Source
Thrown at pkg/auth/tokens/manager.go:108
}
return user.PrincipalIDs, nil
}
// createDerivedToken will create a jwt token for the authenticated user
func (m *Manager) createDerivedToken(jsonInput clientv3.Token, tokenAuthValue string) (apiv3.Token, string, int, error) {
logrus.Debug("Create Derived Token Invoked")
token, _, err := m.GetToken(tokenAuthValue)
if err != nil {
return apiv3.Token{}, "", http.StatusUnauthorized, err
}
tokenTTL, err := exttokenstore.IngestTTL(int64(jsonInput.TTLMillis),
settings.AuthTokenMaxTTLMinutes,
settings.AuthTokenDefaultTTLMinutes)
if err != nil {
return apiv3.Token{}, "", http.StatusInternalServerError, fmt.Errorf("error validating ttl against default and max: %w", err)
}
var unhashedTokenKey string
derivedToken := &apiv3.Token{
UserPrincipal: token.GetUserPrincipal(),
IsDerived: true,
TTLMillis: tokenTTL,
UserID: token.GetUserID(),
AuthProvider: token.GetAuthProvider(),
ProviderInfo: token.GetProviderInfo(),
Description: jsonInput.Description,
ClusterName: jsonInput.ClusterID,
}
derivedToken, unhashedTokenKey, err = m.createToken(derivedToken)
return *derivedToken, unhashedTokenKey, 0, err
}View on GitHub (pinned to 932558d4e6)
Solutions
- Reset both settings to plain integer minute strings: kubectl patch settings.auth-token-max-ttl-minutes and settings.auth-token-default-ttl-minutes (or the UI: Global Settings) — e.g. '0' for unlimited max, '600' for 10h default
- Confirm with: kubectl get settings auth-token-max-ttl-minutes auth-token-default-ttl-minutes -o jsonpath='{..value}'
- Retry token creation after correcting values; no restart is needed since settings are read live
- Note the requested TTLMillis itself cannot cause this error — do not waste time changing the request TTL
Example fix
# before (values with units — every token create returns 500)
kubectl get settings auth-token-max-ttl-minutes auth-token-default-ttl-minutes -o custom-columns=NAME:.metadata.name,VALUE:.value
# auth-token-max-ttl-minutes 1440m
# after (plain integer minutes)
kubectl patch setting auth-token-max-ttl-minutes --type=merge -p '{"value":"1440"}'
kubectl patch setting auth-token-default-ttl-minutes --type=merge -p '{"value":"600"}' Defensive patterns
Strategy: validation
Validate before calling
// pre-flight: both TTL settings must parse as plain integer minutes
for _, s := range []settings.Setting{settings.AuthTokenMaxTTLMinutes, settings.AuthTokenDefaultTTLMinutes} {
if _, err := exttokenstore.ParseTTLToMilliseconds(s); err != nil {
return fmt.Errorf("fix setting %s: %w", s.Name, err)
}
} Type guard
func validTTLSetting(v string) bool {
n, err := strconv.ParseInt(v, 10, 64)
return err == nil && n >= 0
} Try / catch
if _, _, code, err := m.createDerivedToken(input, auth); err != nil {
if code == http.StatusInternalServerError && strings.Contains(err.Error(), "validating ttl") {
alertOnMisconfiguredTTSettings() // server-side fix required, do not retry
}
} Prevention
- Enter TTL settings as bare integers (minutes) — never '600m', '24h', or blank
- Add CI validation on settings manifests that patch auth-token-*-minutes
- Know the encoding: 0 = use default / no max; negative = infinite; requests are clamped, never rejected — only the settings themselves can break this path
When it happens
Trigger: POST to create an API/derived token (e.g. v3/token via Rancher API or 'Create API Key' flow) while auth-token-max-ttl-minutes or auth-token-default-ttl-minutes holds a non-integer value; ParseTTLToDuration appends 'm' and time.ParseDuration fails on inputs like '600mm', '10hm', ''. Every token creation then 500s.
Common situations: Admin enters a duration with a unit suffix ('1440m', '24h') into the Rancher settings UI, which expects bare minutes; automation patches settings.management.cattle.io with formatted durations; setting left empty after a partial upgrade.
Related errors
- unable to get token name from content
- no user store available
- can't find user
- failed to get userId
- InvalidBodyContent
AI-assisted analysis of rancher/rancher@932558d4e6 (2026-08-16).
Data as JSON: /api/errors/ae446eaceb4a5ef3.
Report an issue: GitHub.