go-kit/kit · warning · ErrTokenNotActive
token is not valid yet
Error message
token is not valid yet
What it means
Returned by jwt.NewParser when the underlying jwt.ValidationError has the ValidationErrorNotValidYet bit set: the token's nbf (not before) claim is in the future. The token is well-formed and correctly signed but is not yet within its validity window, so the server refuses it.
Source
Thrown at auth/jwt/middleware.go:43
)
var (
// ErrTokenContextMissing denotes a token was not passed into the parsing
// middleware's context.
ErrTokenContextMissing = errors.New("token up for parsing was not passed through the context")
// ErrTokenInvalid denotes a token was not able to be validated.
ErrTokenInvalid = errors.New("JWT was invalid")
// ErrTokenExpired denotes a token's expire header (exp) has since passed.
ErrTokenExpired = errors.New("JWT is expired")
// ErrTokenMalformed denotes a token was not formatted as a JWT.
ErrTokenMalformed = errors.New("JWT is malformed")
// ErrTokenNotActive denotes a token's not before header (nbf) is in the
// future.
ErrTokenNotActive = errors.New("token is not valid yet")
// ErrUnexpectedSigningMethod denotes a token was signed with an unexpected
// signing method.
ErrUnexpectedSigningMethod = errors.New("unexpected signing method")
)
// NewSigner creates a new JWT generating middleware, specifying key ID,
// signing string, signing method and the claims you would like it to contain.
// Tokens are signed with a Key ID header (kid) which is useful for determining
// the key to use for parsing. Particularly useful for clients.
func NewSigner(kid string, key []byte, method jwt.SigningMethod, claims jwt.Claims) endpoint.Middleware {
return func(next endpoint.Endpoint) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
token := jwt.NewWithClaims(method, claims)
token.Header["kid"] = kid
// Sign and get the complete encoded token as a string using the secret
tokenString, err := token.SignedString(key)View on GitHub (pinned to 78fbbceece)
Solutions
- Sync clocks on all signing and verifying hosts (NTP/chrony)
- Set nbf at (or slightly before) issuance — e.g. time.Now().Add(-30*time.Second) — instead of in the future
- If skew is unavoidable, tolerate it by validating with leeway on the golang-jwt validator instead of relying on the strict default
- Retry the request after (nbf - now) seconds once clocks are correct
Example fix
// before: nbf pushed into the future, verifier clock slightly behind
claims := &jwt.RegisteredClaims{NotBefore: jwt.NewNumericDate(time.Now().Add(2 * time.Minute))}
// after: nbf at issuance minus small skew allowance
claims := &jwt.RegisteredClaims{NotBefore: jwt.NewNumericDate(time.Now().Add(-30 * time.Second))} Defensive patterns
Strategy: retry
Validate before calling
null
Type guard
null
Try / catch
resp, err := ep(ctx, req)
if err != nil && errors.Is(err, jwt.ErrTokenNotActive) {
// transient skew: wait briefly and retry once; if it persists, alert on clock sync
time.Sleep(2 * time.Second)
resp, err = ep(ctx, req)
} Prevention
- Set nbf slightly in the past (e.g. now-30s) to absorb normal skew
- Keep signer and verifier clocks NTP-synced; alert on measurable drift
- Prefer golang-jwt validator leeway over disabling nbf entirely
When it happens
Trigger: Clock skew: the verifying server's clock lags behind the issuing server, so a token with nbf=now appears 'not valid yet'; signer deliberately sets nbf in the future; tokens minted with nbf computed in the wrong unit (milliseconds) so it lands far ahead; tokens generated on a host with a wrong system clock.
Common situations: Container/VM clock drift in clusters; multi-region deployments where issuer and verifier disagree on time; switching identity providers that populate nbf differently; CI environments with frozen/skewed clocks.
Related errors
- token up for parsing was not passed through the context
- JWT was invalid
- JWT is expired
- JWT is malformed
- unexpected signing method
AI-assisted analysis of go-kit/kit@78fbbceece (2026-08-15).
Data as JSON: /api/errors/b65a90ab269ae355.
Report an issue: GitHub.