JWT Token Expired Error
Fix 'jwt expired' errors. Learn how JWT expiration works, how to check the exp claim, and implement token refresh flows.
What Does This Error Mean?
The 'jwt expired' error means the token's expiration time (the 'exp' claim) has passed. JWTs include an expiration timestamp to limit their validity period. Once expired, the token is rejected by the server and must be refreshed or reissued.
Common Causes
Token lifetime is too short and expires during normal usage
Client clock is significantly ahead of the server clock (clock skew)
User session extended beyond the original token lifetime
Refresh token also expired with no way to get a new one
Token was issued a long time ago and naturally expired
Server clock drift causing premature expiration
How to Fix It
Check token expiration time
Decode the JWT and check the exp claim to see when it expires.
const decoded = jwt.decode(token)
const expDate = new Date(decoded.exp * 1000)
console.log(`Token expires: ${expDate}`)
console.log(`Is expired: ${Date.now() > decoded.exp * 1000}`)Implement token refresh
Use a refresh token to obtain new access tokens without requiring the user to log in again.
async function getValidToken() {
const token = localStorage.getItem("accessToken")
if (isTokenExpired(token)) {
const refreshToken = localStorage.getItem("refreshToken")
const res = await fetch("/auth/refresh", {
method: "POST",
body: JSON.stringify({ refreshToken })
})
const { accessToken } = await res.json()
localStorage.setItem("accessToken", accessToken)
return accessToken
}
return token
}Account for clock skew
JWT libraries allow you to set a clock skew tolerance in seconds.
// Node.js jsonwebtoken
const jwt = require("jsonwebtoken")
// Allow 30 seconds clock skew
jwt.verify(token, secret, { clockTolerance: 30 })
// Or use the exp claim directly
const isExpired = (decoded, skewSec = 30) => {
return Date.now() / 1000 > decoded.exp + skewSec
}Before & After Examples
// ❌ No refresh logic
const res = await fetch("/api/data", {
headers: { Authorization: `Bearer ${token}` }
}) // Returns 401 if token expired// ✅ Auto-refresh on 401
const res = await fetch("/api/data", {
headers: { Authorization: `Bearer ${await getValidToken()}` }
})Related Tools
Use these tools to debug and fix this error:
Related Guides
Deepen your understanding with these guides and tutorials:
Related Errors
Other common errors in this category:
JWT Malformed Error
Fix 'jwt malformed' errors when decoding or verifying JWT tokens. Learn the correct JWT format and how to debug invalid tokens.
JWT Invalid Signature Error
Fix 'invalid signature' JWT errors. Learn how JWT signatures work, why they fail, and how to use the correct secret key.
CSRF Token Mismatch Error
Fix 'CSRF token mismatch' errors in web forms and APIs. Learn how CSRF protection works and how to properly include tokens in requests.
Frequently Asked Questions
How long should a JWT be valid?
Access tokens should be short-lived (15-60 minutes) to minimize the impact of token theft. Refresh tokens can last longer (days to months) but should be securely stored.
What happens when a JWT expires during a request?
The request will fail with a 401 Unauthorized response. The client should catch this error, refresh the token, and retry the request.