Uvlio

Command Palette

Search for a command to run...

Back to articles
Technical Article

Reading a JWT: What Decoding Shows and What It Proves

A JSON Web Token is three base64url-encoded segments joined by dots: a header, a payload, and a signature. Two of those three are readable by anyone holding the token, which is the single most important fact about the format and the one most often misunderstood. Decoding is useful for debugging; verification is what establishes trust, and the two steps must never be confused.
Uvlio editorial team by limitcool2026-05-177 min read
Topic coverDeveloperJWT EncoderJWT Decoder

Reading a JWT: What Decoding Shows and What It Proves

A JWT is three base64url segments, and decoding one tells you nothing about whether it is genuine. How to read the claims, and why tokens break in URLs.

Guide subject preview
Understand
Check
Apply
Tool stack
JWT EncoderJWT DecoderURL ParserQuery String Builder
Reading focus
1Understand
2Check
3Apply

Original workflow visual

Reading a JWT: What Decoding Shows and What It Proves

This original Uvlio visual summarizes the practical path from input inspection to output review for this workflow.
1

Understand

Review before moving forward

2

Check

Review before moving forward

3

Apply

Review before moving forward

Maintainer and review note
Maintained by limitcool. Use it to understand the technical model, processing boundaries, privacy risks, and verifiable behavior.
Encoded is not encrypted

The header and payload of a standard signed JWT are base64url text, not ciphertext. Anyone who obtains the token — from a URL, a log file, a browser devtools panel, a Referer header — can read every claim inside it without any key. The signature protects integrity, not confidentiality: it proves the token has not been altered, and proves nothing about who is allowed to see it. Never put anything in a payload that you would not put in a log line.

Decoding is not verifying

A decoder splits the token and base64-decodes two segments. That operation always succeeds on well-formed input, including on a token someone constructed by hand. Verification is a separate step that recomputes the signature using the secret or public key and compares it. A debugging tool showing you a neat, plausible payload is not evidence that the token is genuine. Trusting a claim because it decoded cleanly is the root of a whole family of authentication bugs.

base64url is not base64

JWTs use the URL-safe alphabet: minus and underscore replace plus and slash, and the trailing equals padding is stripped. Pasting a JWT into a standard base64 decoder often fails on the padding or mangles bytes on the substituted characters. This is also why a token can survive one system and break in the next — something helpfully "fixed" the encoding along the way, or a URL decoder turned a legitimate character into something else.

The time claims and the clock problem

exp is the expiry, iat the issue time, and nbf the earliest time the token is valid. All three are numeric Unix timestamps in seconds, not milliseconds, which is a frequent source of tokens that appear to expire in 1970 or in the far future. Because clocks between issuer and verifier drift, implementations usually allow a small leeway of a few seconds. If tokens fail intermittently right at issue time, an nbf claim combined with a fast clock on the issuing server is a good first suspect.

Why tokens break in URLs

A JWT in a query string is exposed in browser history, server access logs, and the Referer header sent to third parties. It is also fragile: tokens are long, some proxies and older clients truncate URLs beyond a few thousand characters, and a token that is percent-encoded once by one layer and again by another arrives corrupted. If a token works in a header and fails in a link, compare the two strings character by character before suspecting anything else — double encoding is the usual answer.

alg is an instruction, and that is the danger

The header names the signing algorithm, and a naive verifier reads it and does what it says. Two classic attacks follow. The first sets alg to none and drops the signature entirely. The second switches an RS256 token to HS256 so that the server verifies using the public key as if it were an HMAC secret — and the public key is public. The fix in both cases is the same: the verifier decides which algorithm is acceptable in advance and rejects anything else, rather than taking direction from the token it is checking.

A practical decoding workflow

When a token misbehaves, decode the header and payload first and write down alg, exp, iat, nbf and any audience or issuer claims. Confirm the clock units are seconds. Compare the raw token string from the working path and the failing path character by character. Only after the payload is understood should you move to signature verification with the expected algorithm and key. If the algorithm in the header is not on your allowlist, reject the token without attempting verification.

Common Questions

Is a JWT encrypted?

A standard signed JWT is not. The payload is base64url text that anyone with the token can read. Encryption requires the separate JWE format.

Can I trust the claims in a token I just decoded?

No. Decoding always succeeds, including on a forged token. Only signature verification against the correct key establishes trust.

Why does my JWT fail after I copy it out of a URL?

Usually encoding. JWTs use base64url, and a URL decoder or a double-encoding layer can alter the minus, underscore or padding characters.

My token expires immediately. What should I check first?

Whether exp is in seconds. A millisecond timestamp is a thousand times too large, and a seconds value fed to a millisecond parser lands in 1970.