{"record":{"id":"c882a81b84591d7f","repo":"ory/hydra","slug":"token-used-before-issued","errorCode":null,"errorMessage":"Token used before issued","messagePattern":"Token used before issued","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fosite/token/jwt/map_claims.go","lineNumber":120,"sourceCode":"\t}\n\treturn 0, false\n}\n\n// Validates time based claims \"exp, iat, nbf\".\n// There is no accounting for clock skew.\n// As well, if any of the above claims are not in the token, it will still\n// be considered a valid claim.\nfunc (m MapClaims) Valid() error {\n\tvErr := new(ValidationError)\n\tnow := TimeFunc().Unix()\n\n\tif !m.VerifyExpiresAt(now, false) {\n\t\tvErr.Inner = errors.New(\"Token is expired\")\n\t\tvErr.Errors |= ValidationErrorExpired\n\t}\n\n\tif !m.VerifyIssuedAt(now, false) {\n\t\tvErr.Inner = errors.New(\"Token used before issued\")\n\t\tvErr.Errors |= ValidationErrorIssuedAt\n\t}\n\n\tif !m.VerifyNotBefore(now, false) {\n\t\tvErr.Inner = errors.New(\"Token is not valid yet\")\n\t\tvErr.Errors |= ValidationErrorNotValidYet\n\t}\n\n\tif vErr.valid() {\n\t\treturn nil\n\t}\n\n\treturn vErr\n}\n\nfunc (m MapClaims) UnmarshalJSON(b []byte) error {\n\t// This custom unmarshal allows to configure the\n\t// go-jose decoding settings since there is no other way","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/fosite/token/jwt/map_claims.go#L102-L138","documentation":"This error comes from JWT claims validation in fosite's jwt package. During `Valid()`, `VerifyIssuedAt(now, false)` fails when the token's `iat` claim is in the future relative to the verifier's clock, i.e. the token is being used before its issue time. The library rejects such tokens because a future `iat` usually indicates clock skew or a forged/misconfigured token.","triggerScenarios":"Calling ParseWithClaims on a JWT whose `iat` claim is greater than the current time — typically when the issuer's clock is ahead of the verifier's clock, or the token was crafted with a wrong `iat`.","commonSituations":"Distributed deployments where the OAuth server and resource server clocks drift apart; tokens issued by a service with an unsynchronized NTP daemon; containers/VMs resumed from snapshots with stale clocks; manually minted test tokens with a mistaken epoch timestamp.","solutions":["Synchronize clocks on the token issuer and verifier (enable NTP/chrony and verify with `timedatectl status`).","Re-mint the token so its `iat` is <= current time.","If small skew is acceptable, parse with a leeway-enabled validator that subtracts skew from `now` before VerifyIssuedAt.","Check for wrongly configured time in containers (host clock passthrough) and restarted VMs."],"exampleFix":"// before: strict parsing fails on minor skew\nclaims, err := jwt.ParseWithClaims(raw, &claims, keyFunc)\n// after: allow e.g. 2 minutes of leeway by skewing the reference time\nnow := time.Now().Add(-2 * time.Minute)\nclaims, err := jwt.ParseWithClaims(raw, &claims, keyFunc, jwt.WithTimeFunc(func() time.Time { return now }))","handlingStrategy":"validation","validationCode":"// before parsing, sanity-check token timestamps against local clock\nfunc iatLooksSane(claims jwt.MapClaims, leeway time.Duration) bool {\n    iat, ok := claims[\"iat\"].(float64)\n    return ok && time.Unix(int64(iat), 0).Before(time.Now().Add(leeway))\n}","typeGuard":null,"tryCatchPattern":"// treat expired/issued-at failures as auth failures, not crashes\nif err := claims.Valid(); err != nil {\n    var vErr *jwt.ValidationError\n    if errors.As(err, &vErr) && vErr.Errors&jwt.ValidationErrorIssuedAt != 0 {\n        return nil, fmt.Errorf(\"token not yet valid (clock skew?): %w\", err)\n    }\n    return nil, err\n}","preventionTips":["Run NTP/chrony on all hosts and containers issuing or verifying tokens","Allow explicit leeway (1-2 min) in token validation","Monitor clock drift across the fleet","Never hand-mint tokens with guessed iat values"],"tags":["jwt","oauth2","clock-skew","validation"],"backgroundTag":"jwt-token-not-yet-valid","analyzedSha":"4174065ffb052799890f7480f5360a877a67ffc1","analyzedAt":"2026-09-03T14:52:41.581Z","contentChangedAt":"2026-09-03T14:52:41.581Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}