nats-io/nats-server · error
authorized user on account %q outside of valid connect times
Error message
authorized user on account %q outside of valid connect times
What it means
The auth callout's user JWT carries time restrictions (validateTimes), and the connection attempt falls outside the allowed window, so the server refuses to assign the account and rejects the user. This enforces connect-time windows encoded in the user claims returned by the callout.
Source
Thrown at server/auth_callout.go:195
jwtIssuer = arc.IssuerAccount
}
if jwtIssuer != issuer {
if !isOperatorMode {
return _EMPTY_, fmt.Errorf("wrong issuer for auth callout response on account %q, expected %q got %q", account, issuer, jwtIssuer)
} else if !acc.isAllowedAcount(jwtIssuer) {
return _EMPTY_, fmt.Errorf("account %q not permitted as valid account option for auth callout for account %q",
arc.Issuer, account)
}
}
return jwtIssuer, nil
}
getExpirationAndAllowedConnections := func(arc *jwt.UserClaims, account string) (time.Duration, map[string]struct{}, error) {
allowNow, expiration := validateTimes(arc)
if !allowNow {
c.Errorf("Outside connect times")
return 0, nil, fmt.Errorf("authorized user on account %q outside of valid connect times", account)
}
allowedConnTypes, err := convertAllowedConnectionTypes(arc.User.AllowedConnectionTypes)
if err != nil {
c.Debugf("%v", err)
if len(allowedConnTypes) == 0 {
return 0, nil, fmt.Errorf("authorized user on account %q using invalid connection type", account)
}
}
return expiration, allowedConnTypes, nil
}
assignAccountAndPermissions := func(arc *jwt.UserClaims, account string) (*Account, error) {
// Apply to this client.
var err error
issuerAccount, err := getIssuerAccount(arc, account)
if err != nil {
return nil, errView on GitHub (pinned to 3a66a489d2)
Solutions
- Re-request authorization so the callout issues a user JWT with a current, valid time window.
- Fix clock synchronization (NTP) between the callout service and the NATS server.
- Widen the time window in the callout's claim generation for long-running connections.
Example fix
// before arc.Expires = time.Now().Add(5 * time.Second) // expires almost immediately // after arc.Expires = time.Now().Add(30 * time.Minute)
Defensive patterns
Strategy: validation
Validate before calling
vr := jwt.CreateValidationResults()
arc.Validate(vr)
now := time.Now()
if arc.Expires > 0 && now.After(time.Unix(arc.Expires, 0)) {
return errors.New("user claims expired; request a fresh authorization response")
} Try / catch
if err != nil && strings.Contains(err.Error(), "outside of valid connect times") {
// request new credentials from the callout and reconnect
} Prevention
- Issue user JWTs with generous windows relative to expected connection times.
- Synchronize clocks with NTP across callout and server.
- Refresh credentials before expiry on long-lived connections.
When it happens
Trigger: The AuthorizationResponseClaims' user JWT has valid from/until style time constraints and validateTimes returns allowNow=false because the current server time is before the start or after the end of the window.
Common situations: Temporary/short-lived user JWTs issued by the callout expiring before a reconnect; clock skew between callout issuer and server making an apparently-valid JWT outside its window.
Related errors
- operators do not allow authorization callouts to be configur
- authorization response had validation errors: %v
- error non operator mode account %q: attempted to use issuer_
- wrong issuer for auth callout response on account %q, expect
- account %q not permitted as valid account option for auth ca
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/92b1148da71c35b7.
Report an issue: GitHub.