JSON Web Tokens (JWTs) are the backbone of modern authentication. They're in your Authorization headers, your cookies, your OAuth responses. Every developer who works with APIs needs to understand what a JWT contains — and decoding one is the fastest path to debugging auth issues, understanding expiration behavior, and verifying that your backend is generating the right claims.
JWT Structure: The Three Parts
A JWT is three Base64URL-encoded strings separated by dots: Header.Payload.Signature. The header specifies the algorithm (alg) and token type (typ). The payload contains the claims — standardized fields like sub (subject), exp (expiration), iat (issued at), and any custom claims your app defines. The signature verifies that the header and payload weren't tampered with.
Decoding a JWT doesn't require the signing secret. The header and payload are just Base64URL-encoded JSON — any tool (or a single line of JavaScript) can decode them. What requires the secret is verification — confirming the signature is valid. For debugging purposes, decoding without verification is often exactly what you need.
Common JWT Claims and What They Mean
sub (Subject): The unique identifier for the user or entity the token represents. Often a user ID. iss (Issuer): Who created the token — your auth service, Auth0, Firebase, etc. aud (Audience): Who the token is intended for. exp (Expiration): Unix timestamp after which the token is invalid. iat (Issued At): Unix timestamp when the token was created. jti (JWT ID): A unique identifier for this specific token, used to prevent replay attacks.
Custom claims are anything else your application adds: roles, permissions, plan tier, tenant ID. These live in the payload alongside the standard claims and are readable by any client that holds the token.
JWT Debugging: The Most Common Issues
"Token expired" errors: The exp claim is in the past. Check the difference between exp and iat to understand the intended token lifetime, and compare exp to your system clock (timezone issues are a common culprit).
"Invalid signature" errors: The token was modified after signing, or you're using the wrong secret/key. Decode the header to confirm the algorithm, then verify you're using the matching key.
"Token not yet valid" errors: Some JWTs include an nbf (Not Before) claim. If the issuing server's clock is ahead of yours, you'll get this error on tokens that are technically valid. NTP sync issues cause this in containerized environments.
HS256 vs RS256 vs ES256
HS256 (HMAC-SHA256) is symmetric — the same secret signs and verifies the token. Simple but requires every service that verifies the token to know the secret. Best for monolithic applications.
RS256 (RSA-SHA256) is asymmetric — a private key signs, a public key verifies. Services can verify JWTs without knowing the signing secret. Best for distributed systems and when exposing verification to third parties.
ES256 (ECDSA with P-256) is asymmetric like RS256 but uses elliptic curve cryptography for smaller key sizes and faster operations. Increasingly popular for mobile and IoT use cases.
JWT debugging is a daily activity for any developer building authentication. Having a fast, trustworthy decoder in your toolkit saves hours of frustration. Paste your token into the decoder to instantly inspect headers, payload claims, expiration times, and algorithm details.
JWT Decoder — free, instant, no signup
100% client-side. Your data never leaves your browser.
Decode Your JWT Token →