Done
Free · No sign-up · 100% client-side

JWT Debugger Pro

Decode a JWT, inspect its claims, and verify HS256 signatures with a shared secret. Timestamps are humanized automatically. Everything happens in your browser — nothing is ever uploaded.

Last reviewed: August 24, 2026 Built by Khalil Rahman 100% browser-based
Ready
Try:

Header

Base64Url
Waiting for token…

Payload

Claims
Waiting for token…

Signature

HMAC
Waiting for token…
Do not paste production secrets. Use a test secret for exploration. Even though everything stays in your browser, saving sensitive values in a form field is an unnecessary risk — autocomplete is disabled here, but be careful on any tool.

How to decode and debug a JWT

  1. Paste the token. A valid JWT is three Base64Url sections separated by two dots: header.payload.signature.
  2. Read the parts. The header tells you the signing algorithm (alg) and token type. The payload contains the claims. The signature is the raw bytes that prove the token was signed by the server holding the secret.
  3. Inspect claims. Standard registered claims — exp, iat, nbf, iss, aud, sub — are listed with a reserved tag. Timestamp claims are automatically humanized.
  4. Verify (HS256 only). Enter the shared secret and click Verify. The tool recomputes the HMAC-SHA256 signature of header.payload using your secret and compares it to the signature in the token.

Understanding JSON Web Tokens

A JSON Web Token is a compact, URL-safe way to transmit claims between two parties. It is defined in RFC 7519 and used by virtually every modern authentication system — OAuth 2.0, OpenID Connect, most API gateways, and most single-sign-on platforms.

A JWT has three parts separated by dots:

  • Header. A JSON object with at least alg (the signing algorithm) and typ (usually "JWT").
  • Payload. A JSON object with claims — user ID, role, expiry time, and any custom data your server wants to include.
  • Signature. The cryptographic proof that the header and payload were signed by whoever holds the secret (HS256) or private key (RS256, ES256).

Each part is Base64Url-encoded and joined with dots. Base64Url is not encryption — anyone can decode it in one line of JavaScript. That is why you must never put sensitive data in the payload.

The seven registered claims, explained

  • iss — Issuer. Who created the token. Often a URL or a service name.
  • sub — Subject. Who the token is about. Usually the user ID.
  • aud — Audience. Who is allowed to consume the token. A token for one service must not be accepted by another.
  • exp — Expiration Time. Unix timestamp after which the token is invalid. Servers must reject tokens with an exp in the past.
  • nbf — Not Before. Unix timestamp before which the token is invalid.
  • iat — Issued At. Unix timestamp when the token was minted. Useful for detecting old tokens and computing "expires in" client-side.
  • jti — JWT ID. A unique identifier for the token. Used for replay protection and revocation lists.

You can also include custom claims — role, permissions, tenant ID, feature flags. Those are not registered but are equally readable.

Common JWT problems this tool helps you catch

  • Expired tokens. If the API returns a 401 and you are not sure why, paste the token — exp in the past is the answer more often than people expect.
  • Wrong audience. A token issued for service-a will be rejected by service-b even if it is valid. The claims table makes the audience visible.
  • Wrong role. If your frontend hides a button but the API still returns 403, check that the role or scope claim is actually what your server expects.
  • Signatures that were never signed. If alg is none, the token is unsigned. Some servers historically accepted these — a famous vulnerability class called "algorithm confusion". Check that your server rejects alg: none.
  • Wrong secret across environments. A token from staging will fail to verify against production's secret. Confirm which environment the token was issued in before assuming the token is broken.

⚠️ HS256 vs RS256 vs ES256

This tool verifies HS256 tokens only. HS256 uses HMAC-SHA256 with a shared secret — the same secret signs and verifies. RS256, ES256, and PS256 use asymmetric keys: the server signs with a private key and you verify with a public key fetched from a JWKS endpoint. If you paste one of these tokens, the tool will detect the algorithm and tell you it is unsupported, so you are not fooled by a "signature mismatch" message that has nothing to do with tampering.

Khalil Rahman

Full-stack developer and founder of SkillsInsider. I've debugged more JWTs than I can count, and I built this tool because most decoders hide the interesting parts — the expired exp, the wrong aud, the algorithm that silently changed. Send me a message if a token fails to verify and you want to help figure out why.

HS256 Verify

Web Crypto API — not a plugin

Humanized Timestamps

exp, iat, nbf shown as local dates

Pretty JSON

Formatted header and payload

Copy Parts

One-click copy each section

Found this useful? Leave a quick rating

More developer tools

Frequently asked questions

A JWT decoder splits a JSON Web Token into its three parts — header, payload, and signature — and Base64Url-decodes each one into readable JSON. This tool also humanizes timestamp claims like exp and iat, shows whether the token has expired, and can verify HS256 signatures using a shared secret.

Yes. All decoding and verification happens in your browser using JavaScript and the Web Crypto API — your token is never transmitted to a server. That said, do not paste real production secrets into any browser tool unless you understand the risk. Use a test secret and a test token when exploring. If you need to verify a production token, do it in your own development environment.

No. A standard JWT is only Base64Url-encoded, not encrypted. Anyone who intercepts a JWT can read its payload. That is why sensitive values like passwords, credit card numbers, and API keys must never be placed in a JWT payload. JWE (JSON Web Encryption) tokens are the exception, but they are a different format from a standard JWT and are not decoded by this tool.

The exp, iat, nbf, and auth_time claims are Unix epoch timestamps — the number of seconds since 1 January 1970 UTC. This tool automatically converts those values into your browser's local date and time and displays them under the raw number in the claims table.

Not yet. This tool verifies HS256 (HMAC with SHA-256) tokens only, because HMAC needs only a shared secret. RS256, ES256, and PS256 use public-key cryptography — verification requires the issuer's public key, which must be fetched from a JWKS endpoint. If you paste one of these tokens, the tool detects the algorithm and tells you it is not supported, rather than falsely reporting a signature mismatch.

The most common causes: the secret is wrong (many people confuse the HS256 signing secret with a public key or a password), the token was signed by a different environment (a staging token tested against a production secret), or the token has actually been tampered with. Check that the header (especially alg) and the payload match what you expect before assuming the signature is wrong.

alg: none is an unsigned JWT — the header claims there is no signature. It is allowed in the spec but should never be accepted by a production server. If you see alg: none in a token, treat it as untrusted regardless of what the payload claims. Many famous JWT vulnerabilities have come from servers that accepted alg: none when they should have required a signature.

No. Everything runs in your browser. The only network requests after page load are the Bootstrap Icons stylesheet and, if you accept the cookie banner, Google Analytics — which sees the page visit but never the token you paste. Nothing about your token or secret is ever transmitted.