Fehlermeldung
"nbf" claim timestamp check failed
jose (JavaScript) — JWTClaimValidationFailed, code ERR_JWT_CLAIM_VALIDATION_FAILED
Was der Fehler bedeutet
Das Token trägt einen Claim `nbf` („not before“), der nach der Uhr des Prüfers noch in der Zukunft liegt, deshalb lehnt jose es als noch nicht gültig ab. Die Signatur und die übrigen Claims können völlig in Ordnung sein; der Fehler betrifft nur die Zeit. Fast immer bedeutet er, dass die Uhren von Aussteller und Prüfer um mehr als die von dir erlaubte Toleranz voneinander abweichen (standardmäßig null).
Warum der Fehler auftritt
Die Uhr des Prüfers geht gegenüber der des Ausstellers nach
häufigViele Aussteller setzen `nbf` auf den Ausstellungszeitpunkt. Geht die Uhr des prüfenden Hosts auch nur wenige Sekunden nach, stammt jedes frisch ausgestellte Token für genau diese Zeitspanne „aus der Zukunft“. Container und VMs übernehmen die Uhr des Hosts, deshalb legt ein einziger driftender Host alle Dienste darauf auf einmal lahm.
Token sofort nach dem Ausstellen verwendet, ohne Toleranz
häufigTests und Aufrufe zwischen Diensten stellen oft ein Token aus und senden es innerhalb von Millisekunden. Steht `clockTolerance` auf dem Standardwert von 0 Sekunden, reicht schon die normale Uhrenabweichung zwischen zwei Rechnern, damit die Prüfung sporadisch fehlschlägt.
Der Aussteller hat nbf absichtlich in die Zukunft gelegt
gelegentlichManche Systeme stellen Tokens im Voraus aus, die erst später gültig werden (geplante Jobs, zeitversetzt gültige Links). Wird ein solches Token zu früh verwendet, ist die Ablehnung korrekt – der Aufrufer muss bis `nbf` warten.
nbf in Millisekunden geschrieben
seltenZeitangaben in JWTs sind Sekunden seit der Epoche (RFC 7519, NumericDate). Ein Aussteller, der `Date.now()` hineinschreibt, erzeugt ein `nbf` etwa 50.000 Jahre in der Zukunft, und das Token wird nie gültig.
So behebst du den Fehler
- 1.
Kleine, explizite Uhrenabweichung zulassen
`clockTolerance` akzeptiert Sekunden oder einen String mit einer Zeitdauer. 30–60 Sekunden fangen die Drift im echten Betrieb ab; die Option ist kein Weg, Tokens Minuten zu früh zu akzeptieren.
js import { jwtVerify } from "jose"; const { payload } = await jwtVerify(token, jwks, { algorithms: ["ES256"], clockTolerance: "30s", // applies to nbf, exp and iat }); - 2.
Zeitachse ausgeben, bevor du die Konfiguration änderst
Vergleiche `nbf` mit der aktuellen Zeit des Prüfers. Eine Differenz von Sekunden deutet auf Uhrenabweichung hin, eine von Stunden auf einen Fehler mit Zeitzone oder Einheit beim Aussteller, ein 13-stelliges `nbf` auf Millisekunden.
js import { decodeJwt } from "jose"; const { iat, nbf, exp } = decodeJwt(token); const now = Math.floor(Date.now() / 1000); console.log({ iat, nbf, exp, now, nbfInSeconds: nbf - now }); - 3.
Driftende Uhr korrigieren
Betreibe NTP (chrony oder systemd-timesyncd) auf jedem Host, der Tokens ausstellt oder prüft. Die Toleranz verdeckt kleine Abweichungen; große sollte sie nicht verdecken müssen.
bash timedatectl status # "System clock synchronized: yes" chronyc tracking # offset from the NTP reference date -u +%s # compare with the token's nbf