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

  1. 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
  2. Confirm with: kubectl get settings auth-token-max-ttl-minutes auth-token-default-ttl-minutes -o jsonpath='{..value}'
  3. Retry token creation after correcting values; no restart is needed since settings are read live
  4. 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

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


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