Fehlermeldung
jwt expired
Was der Fehler bedeutet
TokenExpiredError von jsonwebtoken: Der Claim exp des Tokens (ein Unix-Zeitstempel in Sekunden) liegt vor der aktuellen Uhrzeit des Prüfers. Die Signatur selbst kann völlig gültig sein – das Token hat einfach die Laufzeit überschritten, die ihm der Aussteller gegeben hat. Das Fehlerobjekt enthält in expiredAt den genauen Zeitpunkt.
Warum der Fehler auftritt
Das Token ist tatsächlich abgelaufen
häufigKurzlebige Access Tokens (5–60 Minuten) sind die Regel; ein Client, der ein Token zwischenspeichert und später wiederverwendet, oder ein Hintergrundjob, der ein Token über einen langen Lauf hinweg hält, läuft planmäßig genau in diesen Fehler. Die Lösung ist ein Refresh-Flow, keine längere Laufzeit.
Uhrenabweichung zwischen Aussteller und Prüfer
häufigGeht die Uhr des prüfenden Servers gegenüber der des Ausstellers vor, gelten Tokens zu früh als „abgelaufen“ – manchmal schon im Moment ihrer Ausstellung. Container und VMs ohne NTP driften überraschend schnell; eine Abweichung von zwei Minuten genügt, um Tokens mit weniger als einer Stunde Laufzeit sporadisch scheitern zu lassen.
exp in der falschen Einheit geschrieben
gelegentlichDie Spezifikation (RFC 7519) definiert exp in Sekunden. Code, der einmal zu oft durch 1000 teilt, erzeugt Zeitstempel im Jahr 1970, sodass jedes Token sofort abgelaufen ist. Der umgekehrte Fehler – Date.now() (Millisekunden) in exp geschrieben – löst diesen Fehler gar nicht aus: Er erzeugt Zeitstempel mehr als 56.000 Jahre in der Zukunft, und das Token läuft nie ab.
So behebst du den Fehler
- 1.
Kleine Uhrenabweichung explizit zulassen
clockTolerance akzeptiert Sekunden und gilt für exp und nbf. Halte den Wert klein (30–60 s) – er soll Uhrendrift abfangen, nicht die Laufzeit von Tokens verlängern.
js jwt.verify(token, publicKey, { algorithms: ["ES256"], clockTolerance: 30, // seconds of tolerated skew }); - 2.
exp untersuchen, bevor du der Uhr die Schuld gibst
Dekodiere die Claims und gib exp neben deiner aktuellen Zeit aus. Sieht exp aus wie 1.7e12, hast du einen Fehler mit Millisekunden; liegt es Minuten in der Vergangenheit, brauchst du eine Refresh-Logik.
js const { exp } = jwt.decode(token); console.log("exp:", new Date(exp * 1000).toISOString()); console.log("now:", new Date().toISOString()); - 3.
Uhren synchronisieren und einen Refresh-Pfad ergänzen
Betreibe NTP (chrony/systemd-timesyncd) auf den prüfenden Hosts und implementiere clientseitig einen Token-Refresh bei 401-Antworten. Bring ignoreExpiration: true nie in die Produktion – damit wird jedes abgeflossene Token zu dauerhaft gültigen Zugangsdaten.