How to Check If a JWT Has Expired (exp, iat and nbf Explained)
Check whether a JWT is expired by reading its exp claim, convert iat and nbf to dates, and fix common errors such as millisecond timestamps and clock skew.
The short answer
A JWT has expired when the current time is at or after the value in its exp claim. exp is a Unix timestamp in seconds, so you convert it to a date and compare it with now. Paste the token into the JWT Decoder and it reads exp and iat for you, shows both as dates in your local time, and marks the token Expired or Valid based on the expiry time alone.
The three time claims in a JWT
The JWT standard (RFC 7519) defines three optional time claims. All three use "NumericDate": the number of seconds since 1970-01-01 00:00:00 UTC.
| Claim | Name | What it means |
|---|---|---|
exp | Expiration time | The token must not be accepted on or after this time |
nbf | Not before | The token must not be accepted before this time |
iat | Issued at | When the token was created; useful for working out its age |
None of them is mandatory in the standard. Your API or identity provider decides which ones it sets and checks. Many access tokens carry exp and iat; some also carry nbf.
How to check expiry with the decoder
Authorization header, drop the word Bearer and the space before pasting.- ✓ Valid JWT structure means the header and payload decoded as JSON.
- ⚠ Expired or ✓ Valid appears only if the payload has an exp claim, followed by the expiry date and time.
- Issued: shows the iat date and time, if present.
nbf, sub, aud, iss and any custom ones. Copy JSON copies the decoded payload.Dates are shown in your browser's local time zone. A token that "expires at 8:30 PM" in India expires at 15:00 UTC.
Worked example
Here is a payload from a short-lived access token:
{"sub":"user_42","iat":1791900000,"nbf":1791900000,"exp":1791903600}
Converting each value:
iat1791900000 = 13 October 2026, 14:00:00 UTC (7:30 PM IST)nbf1791900000 = the same moment, so the token is usable immediatelyexp1791903600 = 13 October 2026, 15:00:00 UTC (8:30 PM IST)
exp minus iat is 3,600 seconds, so this token lives for 60 minutes. Any request after 8:30 PM IST that day should be rejected with this token, and the client should use a refresh token or sign in again.
If you need to convert a timestamp by hand, the Unix Timestamp Converter does it, and the guide to Unix timestamps, seconds vs milliseconds explains the formats.
Checking nbf yourself
The decoder does not evaluate nbf. If your token has it, compare it with the current time:
- If now is earlier than
nbf, a correct server will reject the token as "not yet valid", even though it is not expired. - This often shows up when the server that issued the token and the server checking it have clocks a little apart.
The standard allows a small leeway, usually no more than a few minutes, for clock differences. Many JWT libraries have a setting for it (often called leeway or clock tolerance).
Why a token can be rejected even though it shows "Valid"
The Valid label in the decoder only means "the exp time has not passed yet". It does not mean the token will be accepted. A server may still reject it because:
- The signature is wrong. The decoder does not verify signatures; that needs the secret or public key, and should happen on your server. Anyone can edit a payload and re-encode it, so never trust decoded claims on their own.
nbfis in the future, as above.- The audience or issuer does not match. Check
audandissin the payload against what your API expects. - The token was revoked. Logging out, a password change or an admin action can invalidate tokens on the server side before
exp. - Clock skew. If your server's clock runs fast, it may see the token as expired a minute or two early.
Common mistakes with exp
Using milliseconds instead of seconds
JavaScript's Date.now() returns milliseconds. If a developer writes that straight into exp, the value is 1,000 times too large. 1791903600000 read as seconds is a date in the year 58753, so the token effectively never expires. Real expiry values today are 10 digits long; 13 digits is a red flag.
The opposite mistake happens when reading: new Date(exp) in JavaScript treats the number as milliseconds, so new Date(1791903600) gives 21 January 1970. Multiply by 1,000 first: new Date(exp * 1000).
Forgetting time zones
exp is always UTC-based. The decoder shows it in your local time, but logs on your server may print UTC. When comparing, make sure both are in the same zone.
Treating a missing exp as "valid forever"
If the decoder shows no expiry line, the token has no exp claim. That is allowed by the standard, but for access tokens it is usually a security risk, because a leaked token keeps working until the signing key changes.
Very long lifetimes
An access token that lives for days or months gives an attacker a long window if it leaks. Short-lived access tokens with a separate refresh process are the common pattern.
Privacy and safety tips
The decoder splits the token and Base64URL-decodes the header and payload in your browser. Even so, treat production tokens like passwords:
- Prefer test tokens, or tokens that have already expired, when debugging.
- Do not paste live tokens into chat apps, tickets or screenshots.
- Remember that a JWT payload is encoded, not encrypted. Anyone with the token can read its claims, so never put secrets in it.
New to JWTs? Start with what a JWT token is and how it works, and see the Base64 guide for how the Base64URL encoding in each part differs from standard Base64.
Frequently asked questions
How do I know if a JWT is expired?
Read the exp claim in the payload. It is a Unix timestamp in seconds; if the current time is at or after it, the token has expired. The JWT Decoder shows Expired or Valid with the date.
Is exp in seconds or milliseconds?
Seconds since 1 January 1970 UTC, as defined in RFC 7519. A 13-digit exp value usually means someone wrote milliseconds by mistake.
Does the decoder verify the JWT signature?
No. It decodes the header and payload and checks exp against the current time. Signature verification needs the secret or public key and should happen on your server.
What is the nbf claim?
Not before: the time before which the token must not be accepted. The decoder shows it in the Payload tab but does not evaluate it, so compare it with the current time yourself.
Put this guide into practice with our free online tool — no signup required.
Open tool