Fehlermeldung
"exp" claim timestamp check failed
jose (JavaScript) — JWTExpired, code ERR_JWT_EXPIRED
Was der Fehler bedeutet
Die Claim-Validierung von jose hat das Token abgelehnt, weil der Zeitstempel in exp gemessen an der Uhr des Prüfers in der Vergangenheit liegt. Die Signaturprüfung war bereits bestanden – es geht allein um die Aktualität. Für andere Claims meldet jose Fehler nach demselben Muster ("nbf" claim timestamp check failed), wenn ein Token vor seinem Not-Before-Zeitpunkt verwendet wird.
Warum der Fehler auftritt
Das Token hat seine Laufzeit überschritten
häufigAccess Tokens sind bewusst kurzlebig. Ein Client, der Tokens zwischenspeichert, ohne ihren Ablauf zu prüfen, ein Queue-Consumer, der eine Nachricht samt Token erst Stunden nach dem Einreihen verarbeitet, oder ein Test-Fixture mit fest im Code hinterlegtem Token landen alle zwangsläufig hier.
Die Uhr des Prüfers geht gegenüber der des Ausstellers vor
häufigSchon wenige Minuten Uhrenabweichung auf dem prüfenden Host verkürzen die effektive Laufzeit jedes Tokens und können dazu führen, dass frisch ausgestellte Tokens abgelehnt werden. Container übernehmen die Uhr ihres Hosts – eine driftende VM legt alle Pods darauf auf einmal lahm.
In exp steht die falsche Einheit
gelegentlichexp muss Sekunden seit der Epoche enthalten (RFC 7519). Ausstellender Code, der falsch teilt oder ein als Millisekunden serialisiertes Date-Objekt übergibt, erzeugt Tokens, die entweder schon bei der Ausstellung abgelaufen oder für Jahrtausende gültig sind.
So behebst du den Fehler
- 1.
Begrenzte Toleranz für Uhrenabweichung einstellen
jose akzeptiert die Option clockTolerance (Anzahl Sekunden oder ein menschenlesbarer String). Halte den Wert klein; er fängt Uhrendrift ab und verlängert nicht die Laufzeit.
js import { jwtVerify } from "jose"; await jwtVerify(token, key, { algorithms: ["ES256"], clockTolerance: "30s", }); - 2.
Zeitachse ausgeben, bevor du etwas änderst
Vergleiche iat, exp und die aktuelle Zeit des Prüfers. Das Muster verrät die Ursache: exp Sekunden in der Vergangenheit → Problem beim Refresh; exp vor iat → Fehler beim Ausstellen; exp ≈ jetzt, aber Fehlschlag → Uhrenabweichung.
js import { decodeJwt } from "jose"; const { iat, exp } = decodeJwt(token); console.log({ iat: new Date(iat * 1000), exp: new Date(exp * 1000), now: new Date() });