WebToolsPlanet
developer Tools

JWT Debugger

Decode, inspect, and verify JSON Web Tokens (JWT) locally.

Last updated: March 26, 2026

Used 26K+ times
Client-Side Processing
Input Data Stays on Device
Instant Local Execution

What users say

The algorithm confusion attack FAQ is something I've never seen in another JWT tool. Decodes tokens instantly and the expiry badge saves me from manually converting Unix timestamps.
Ryan C.Backend Developer

Find this tool useful? Support the project to keep it free!

Buy me a coffee

What is JWT Debugger?

A JSON Web Token (JWT) is a compact, URL-safe token format defined by RFC 7519 used to securely transmit claims between parties. Every JWT consists of three Base64URL-encoded segments separated by dots: a **Header** (algorithm and token type), a **Payload** (the claims — user ID, roles, expiry, issuer), and a **Signature** (cryptographic proof the token was not tampered with). Because the header and payload are only encoded — not encrypted — they can be decoded by anyone who holds the token. The signature is what makes JWTs trustworthy.

This debugger decodes any JWT instantly in your browser and verifies HMAC signatures (HS256, HS384, HS512) without sending your token or secret to any server. It surfaces the most security-relevant information at a glance: the signing algorithm, expiry time, issued-at timestamp, issuer, audience, and all custom claims. This is the fastest way to understand what a JWT actually contains and whether its signature is valid against a known secret.

How to Use JWT Debugger

1

Paste your JWT string (typically starting with "eyJ...") into the input box — the Header and Payload decode instantly

2

Review the color-coded JSON panels: Header shows the algorithm (alg) and type (typ); Payload shows all claims

3

Check the Expiry badge — it shows "Valid", "Expired", or "No expiry set" based on the "exp" claim and current time

4

If you have the HMAC secret key, paste it into the "Verify Signature" field — a green checkmark confirms the token is untampered

5

Click any claim value to copy it to your clipboard for use in debugging or API testing

Common Use Cases

  • Inspecting authorization tokens returned by OAuth/OIDC login providers (Auth0, Okta, AWS Cognito)
  • Verifying that the correct claims (user ID, roles, permissions) are encoded in a token before debugging an access issue
  • Troubleshooting "Invalid Signature" errors by verifying the token against the known server HMAC secret
  • Checking token expiration — converting the "exp" Unix timestamp to a human-readable date to confirm when a session expires
  • Debugging expired session tokens in a Node.js/Express or Next.js API middleware that returns 401 Unauthorized
  • Verifying the correct "iss" (issuer) and "aud" (audience) claims in an OAuth 2.0 or OIDC flow
  • Inspecting tokens intercepted from mobile app API calls using Charles Proxy or Proxyman during local development
  • Validating tokens from third-party identity providers (Firebase Auth, Supabase, Clerk) to confirm claim structure

Example Input and Output

Decoding a typical HS256 access token — the three dot-separated segments become readable JSON claims:

JWT (paste the full token string)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiJ1c2VyXzEyMyIsIm5hbWUiOiJBbGljZSBTbWl0aCIsInJvbGUiOiJhZG1pbiIsImlhdCI6MTcwNjc0NTYwMCwiZXhwIjoxNzA2ODMyMDAwfQ
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Decoded header + payload
Header:
{
  "alg": "HS256",
  "typ": "JWT"
}

Payload:
{
  "sub":  "user_123",
  "name": "Alice Smith",
  "role": "admin",
  "iat":  1706745600,   → Thu Feb 01 2024 00:00:00 UTC (issued at)
  "exp":  1706832000    → Fri Feb 02 2024 00:00:00 UTC (expires)
}

Status:   ✅ Valid (expires in 23h 59m)
Algorithm: HS256 (HMAC-SHA256)
Signature: ✅ Verified (secret matched)

Privacy Guarantee

Your JWT and HMAC secret are never transmitted. All decoding and cryptographic verification runs in your browser using the Web Crypto API (crypto.subtle). No network request is made. Close the tab and the token is gone — nothing is stored in localStorage or cookies.

HS256 vs RS256 Limitation

This tool verifies HMAC (HS256/384/512) signatures only — you need the shared secret. For RS256/ES256 tokens (issued by Auth0, Okta, AWS Cognito, Firebase), the token can be decoded but signature verification requires the issuer's public key from their JWKS endpoint (e.g., https://your-domain.auth0.com/.well-known/jwks.json). Use the jwt.io debugger for RSA/ECDSA verification.

Security Warning

Never put production user JWTs containing PII (names, emails, roles) into any online tool — including this one. For production debugging, use tokens from a test user or a staging environment. If you must inspect a production token, do it locally using a JWT library in Node.js: const decoded = jwt.decode(token, { complete: true }) — no network involved.

Frequently Asked Questions

Is my JWT sent to a server when I paste it here?
No. All decoding and signature verification runs exclusively in your browser using JavaScript and the native Web Crypto API. Your token and secret never leave your device — they are not transmitted, logged, or stored anywhere. You can verify this by opening browser DevTools → Network tab and confirming no request is made when you paste a token.
What signature algorithms can this tool verify?
This tool supports symmetric HMAC algorithms: HS256 (HMAC-SHA256), HS384 (HMAC-SHA384), and HS512 (HMAC-SHA512). These require a shared secret known to both the token issuer and verifier. Asymmetric algorithms (RS256, RS384, RS512 using RSA keys; ES256, ES384, ES512 using ECDSA) are not yet supported — for those, you need the public key from the issuer's JWKS endpoint.
What happens if a token is expired?
The debugger decodes and displays the full contents regardless of expiry. The expiry status badge shows "Expired" when the current time is past the "exp" claim value, with a timestamp showing how long ago it expired. This lets you inspect tokens from error logs or captured traffic even after they've expired — useful for post-incident debugging.
What are the standard JWT claims and what do they mean?
"iss" (issuer): who created the token (e.g., "https://auth.example.com"). "sub" (subject): who the token represents (e.g., a user ID). "aud" (audience): who the token is intended for (e.g., "api.example.com"). "exp" (expiration): Unix timestamp after which the token is invalid. "iat" (issued at): Unix timestamp when the token was created. "nbf" (not before): Unix timestamp before which the token is invalid. "jti" (JWT ID): unique identifier to prevent token replay attacks. Custom claims (roles, permissions, email) are added alongside these standard ones.
What is the difference between HS256 and RS256?
HS256 (HMAC-SHA256) is a symmetric algorithm — the same secret key is used to both sign and verify the token. It's simple but requires all verifiers to know the secret. RS256 (RSA-SHA256) is asymmetric — the issuer signs with a private key; verifiers check with the corresponding public key (published at a JWKS endpoint). RS256 is preferred for distributed systems where multiple services need to verify tokens without access to the signing secret. Most enterprise identity providers (Auth0, Okta, AWS Cognito) use RS256 by default.
Can I decode a JWT without the secret key?
Yes — decoding (reading the header and payload) requires no secret, because the content is only Base64URL-encoded, not encrypted. Anyone with the token string can read the claims. The secret is only needed to verify the signature — to confirm the token was issued by a trusted party and has not been modified. Never store sensitive data (passwords, payment info) in a JWT payload, as it can be decoded by anyone.
What is an algorithm confusion attack?
An algorithm confusion (or "alg:none") attack occurs when a server accepts any algorithm specified in the JWT header. An attacker can change "alg" to "none" and remove the signature — if the server doesn't validate the algorithm, it accepts the forged token. To prevent this: always explicitly specify the expected algorithm on your server (e.g., jwt.verify(token, secret, { algorithms: ["HS256"] })) — never trust the "alg" field from the token itself.

How This Tool Works

A JWT is three Base64URL-encoded segments joined by dots: header.payload.signature. The tool splits the token at the dots, applies Base64URL decoding (padding-safe, replacing - with + and _ with /), and JSON.parse()s the first two parts. The exp and iat claims are converted from Unix timestamps to human-readable dates using new Date(claim * 1000). Signature verification uses the browser's native Web Crypto API — the HMAC secret is imported as a CryptoKey with crypto.subtle.importKey(), then crypto.subtle.verify() is called with the algorithm from the header against the original encoded "header.payload" bytes. This is cryptographically identical to what a production server does, so a match here confirms the token is authentic and untampered.

Technical Stack

Web Crypto API (HMAC-SHA)Base64URL decodingcrypto.subtle.importKey()crypto.subtle.verify()Client-side only