Tools Nimbus

Why is my JWT invalid

Tools Nimbus is a free, no-signup developer toolkit that runs entirely in your browser, so your data is never uploaded to a server. A JWT is usually invalid for one of four reasons: it is malformed (not three Base64URL parts, or it still carries a "Bearer" prefix), it is expired, its signature does not verify, or it is not yet valid. Paste it into the Tools Nimbus JWT Decoder, free with no signup, to read the claims and see which one it is.

Last updated July 2026

Decode first, diagnose second

"Invalid JWT" is a symptom, not a cause. A JSON Web Token is three Base64URL-encoded parts joined by dots, in the form header.payload.signature, and it can be rejected at several different stages: your library may fail to even parse it, or it may parse fine and then fail a check on the expiry, the not-before time, or the signature. The header and payload are not encrypted, only encoded, so you can always decode and read them to see exactly what the token claims, even when it is being rejected. That is the fastest way to narrow the problem: decode the token, look at alg in the header and exp, nbf, and iat in the payload, and match the symptom to the table below.

Symptom, cause, and fix at a glance

SymptomMost likely causeFix
"Invalid token" before any claim checkMalformed token: not three parts, a Bearer prefix, or stray whitespaceStrip Bearer and whitespace; confirm exactly three dot-separated parts
"Token expired" or 401 after a whileexp claim is in the pastRequest a fresh token; do not edit exp
"Invalid signature"Wrong key, or the token was altered after signingVerify with the exact key the issuer used
Signature fails only across servicesAlgorithm mismatch: HS256 secret used for an RS256 token, or vice versaMatch the header alg to the key type
"Token not yet valid"nbf or iat is in the future (clock skew)Sync clocks (NTP); allow a small leeway window
Decodes to garbled text or will not parseDecoder treats it as standard Base64, not Base64URLDecode as Base64URL (- and _, no padding)

Cause 1: the token is malformed

Before any claim is checked, the token has to parse. A valid JWT is exactly three Base64URL segments separated by two dots. The most common way this breaks is a leftover Bearer prefix: the HTTP Authorization header is Bearer <token>, and if you copy the whole header value into a decoder or library, the literal word Bearerand the space are not part of the token. Trailing whitespace, a newline from a copy-paste, or the token being wrapped in quotes cause the same "invalid token" error. Count the dots: two dots mean three parts, which is a signed JWS. Five parts (four dots) is a JWE, an encrypted token that a plain decoder cannot read. Strip the prefix and any whitespace and try again.

Cause 2: the token is expired

This is the single most common reason a token that used to work suddenly returns a 401. The exp claim is a Unix timestamp in seconds (not milliseconds), and once the current time passes it, every correct verifier rejects the token. Decode the payload, read the exp number, and convert it to a readable date to confirm. People often trip here by treating exp as milliseconds and landing tens of thousands of years in the future, which is the same seconds-versus-milliseconds bug behind a Unix timestamp showing 1970. You cannot fix an expired token by editing exp: changing the payload breaks the signature. Ask the issuer for a new token, or use your refresh token to get one.

Cause 3: the signature does not verify

A JWT signature is computed over the header and payload with a key. When verification fails, the verifier recomputed that signature and got a different value than the token carries. Three things cause this. First, the wrong key: for a symmetric HS256 token both sides must share the exact same secret, and a single trailing space or a base64-decoded-versus-raw mismatch in that secret is enough to fail. Second, an algorithm mismatch: if the header says RS256you must verify with the issuer's RSA public key, not an HMAC secret, and confusing the two is a classic bug (and a security pitfall). Third, tampering: if anything changed the header or payload after signing, the signature will not match by design. Note that decoding still works when the signature is invalid, because decoding does not check it, which is exactly why a decoder is a useful first step.

Cause 4: the token is not yet valid

Less common but confusing: a brand-new token is rejected as "not yet valid." The nbf (not before) claim, and sometimes a strict check on iat(issued at), tells the verifier the token should not be accepted before a given time. If the machine that issued the token and the machine verifying it disagree on the clock, a token minted "now" can look like it is from a few seconds in the future. Synchronize both clocks with NTP, and configure a small leeway (a few seconds) in your verification library so minor skew does not reject legitimate tokens.

Cause 5: Base64URL, not Base64

If the token will not decode at all, or decodes to mojibake, the decoder is probably treating it as standard Base64. JWTs use Base64URL, which swaps + for - and / for _ and typically drops the = padding, so a token is URL- and cookie-safe. A standard Base64 decoder can reject the - and _ characters or misread them. This is the same distinction covered in Base64 vs Base64URL. Use a decoder that understands Base64URL, or convert the alphabet back before decoding with a general Base64 tool.

Read the token in one step

You do not have to guess. Open the JWT Decoder and paste the token; it splits the three parts, decodes the header and payload as Base64URL, and shows the claims as readable JSON, including the alg in the header and the time claims in the payload. Check alg against the key you are verifying with, and check exp against the current time (drop the number into the Unix Timestamp Converter to read it as a date). Because the decoder runs entirely in your browser, the token never leaves your device. Note that a decoder reads a token; it does not verify the signature, which needs the secret or public key and belongs on a trusted server.

How to prevent invalid-JWT errors

  • Always strip the Bearer prefix and trim whitespace before handing a token to a library or decoder.
  • Treat exp, nbf, and iat as Unix seconds, and refresh tokens before they expire instead of editing claims.
  • Match the verification key to the header alg: a shared secret for HS256, the issuer's public key for RS256, and never accept alg: none.
  • Keep server clocks in sync with NTP and allow a few seconds of leeway to absorb skew on nbf and exp.
  • Decode with a Base64URL-aware tool. For picking one, see the free alternative to jwt.io, and browse the Tools Nimbus guides for more developer fixes.

Frequently asked questions

Why is my JWT invalid?+

A JWT is rejected for one of a small set of reasons: it is malformed (not three dot-separated Base64URL parts, or it still has a 'Bearer ' prefix or stray whitespace), it is expired (the exp claim is in the past), its signature does not verify (wrong key or an algorithm mismatch such as HS256 versus RS256), or it is not yet valid (an nbf claim in the future, usually clock skew). Decode the token first to read its claims, then check which of these applies.

How do I know if my JWT is expired?+

Look at the exp claim in the payload. It is a Unix timestamp in seconds, not milliseconds, counting from 1970. If exp is smaller than the current epoch time, the token has expired and any correct verifier will reject it. Decode the token to read exp, then convert that number to a readable date to confirm. Also check iat (issued at) and nbf (not before) if the token is being rejected as not yet valid.

What does 'invalid signature' mean on a JWT?+

It means the verifier recomputed the signature over the header and payload and got a different value than the one in the token. The usual causes are the wrong secret or public key, an algorithm mismatch (the header says RS256 but you verified with an HMAC secret, or vice versa), or the token being altered after it was signed. The header and payload can still be decoded and read even when the signature does not verify.

Why does my JWT decode to garbled text or fail to parse?+

JWTs are encoded with Base64URL, not standard Base64. Base64URL replaces + with - and / with _ and usually drops the = padding. A decoder that expects standard Base64 can choke on those characters or produce garbage. Confirm you have exactly three parts separated by dots, that you removed any 'Bearer ' prefix and whitespace, and that you are decoding as Base64URL.

Can I fix an invalid JWT by editing it?+

No. You cannot edit the payload (for example to push out the expiry) and keep the token valid, because any change to the header or payload invalidates the signature. The only way to get a valid token is to have the issuer sign a fresh one. Editing a JWT is only useful for inspection and debugging, never for extending access.

Is it safe to paste a JWT into an online decoder?+

It depends on whether the tool sends your token to a server. The Tools Nimbus JWT Decoder decodes the header and payload entirely in your browser, so the token never leaves your device. Even so, treat any live access token as a secret: prefer a local decoder, and avoid pasting a token you are actively using into any tool that round-trips it through a backend.

Try these browser-based tools mentioned in this guide. Everything runs locally, so your data never leaves your device.