The tool you need, ready to use

JWT Decoder

Paste a JWT and the header and payload are decoded right away, with a meaning attached to every claim. Then it follows the order a server checks: four checkpoints, namely format, signature, time, and issuer and audience. Add a secret or a public key (PEM, JWK, JWKS) to actually verify the signature, and the time left until exp counts down by the second on the timeline. The token and key never leave your browser.

Last updated 2026-10-22All math stays in your browser
Examples

The token and key are processed only in this browser and are never sent or stored. It is safer not to paste production secrets.

Validity

    Signature check

    Content

    Last updated 2026-10-22Your inputs are not stored

    ROBERIN standardThe tool you need,
    ready to use.
    • Clear at a glanceInputs and results sit where you expect them.
    • Result firstThe key number comes first; the working only when you need it.
    • Ask lessNo sign-up and no unnecessary details.

    Decoding a JWT only reads it: the signature and the time decide whether to trust it

    A JWT (JSON Web Token) is a string made of three parts separated by two dots: a header, a payload and a signature. The first two parts are JSON written as Base64url, so anyone can decode and read them without a key. That is why seeing the content after decoding tells you neither whether the token is genuine nor whether it can be used now. A server accepts a token only after it checks, in order, that the signature is valid, that the expiry time (exp) has not passed, and that the issuer (iss) and audience (aud) are the expected values.

    The tool above decodes the token you paste right away and shows the values and meanings of the header and payload in a table. It then follows the same four checkpoints (format, signature, time, issuer and audience) and marks where the token gets stopped. If you add a secret or a public key (PEM, JWK, JWKS), it actually checks the signature, and the time left until exp counts down by the second on the timeline. The token and key are processed only in the browser and are not sent anywhere.

    When you need to decode a JWT yourself

    • When an API returns 401 Unauthorized: the reason is usually expiry (exp), a token meant for another service (aud) or a key rotation (kid). Paste the token and you can see at which of the four checkpoints it is stopped.
    • When logins end sooner than expected: the gap between iat and exp is the token's lifetime. Access tokens often live only 15 minutes or an hour, so the lifetime and time left shown on screen let you check the setting.
    • When you add OpenID Connect login: check that the ID token's iss, aud, nonce, email_verified and similar values arrive as expected. If you paste the JSON from the provider's jwks_uri as is, the tool checks the signature with the public key whose kid matches.
    • When you are finding out why a permission is missing: claims such as scope, roles and groups are split into chips so you can see whether the needed permission is there. The service defines what the values mean, so compare them with the server configuration.
    • When the server clock and your device clock differ: if you see "not valid yet" or "expired" right after issue, a clock difference may be the cause. Switch the tolerance between 0 s, 60 s and 5 min and watch how the verdict changes.
    • When you need a test token: in "Edit JSON", change the payload and sign it again with a secret to get a token with the values you want. If you edit without the key, you can also see right away that the signature no longer matches.

    How to use it

    1. Add the token: paste the JWT into the token field. It finds only the token even when it is mixed with other text, such as an Authorization: Bearer … header, a token response JSON ({"access_token": "…", "id_token": "…"}) or #id_token=… in a callback URL. If there are several tokens, pick one with the chips.
    2. Check the parts: the token text is colored by header, payload and signature, and the bar below shows the bytes of each part. Hover over a table row and the characters of the token that hold that value are highlighted.
    3. Check the time: the validity section shows the time left until expiry, iat, nbf and exp converted to your device time zone, and the token's lifetime. Choose the clock tolerance that matches the library your server uses.
    4. Check the signature: if alg is an HS algorithm such as HS256, enter the secret. For RS, PS, ES and EdDSA, enter the public key. Enter the issuer and audience your server expects and the fourth checkpoint is checked too.
    5. Edit: choose "Edit JSON" under "Content" to change the header and payload yourself. If the signature check section has a secret or private key, the tool builds a token signed again with the edited content.

    Three parts separated by two dots

    The header and payload are UTF-8 JSON converted to Base64url. Base64url uses - and _ instead of the + and / of ordinary Base64 and drops the trailing = (RFC 7515 section 2), so it can go straight into a URL or an HTTP header. The signature is the bytes computed with a key over the whole text "header.payload", written the same way, so changing even one character of the header or payload makes it stop matching. Below is an HS256 token made with the secret demo-secret-for-roberin-jwt-2026, split into its parts.

    The three parts of the example token
    PartToken textDecodedCharactersBytes
    HeadereyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9{"alg":"HS256","typ":"JWT"}3627
    PayloadeyJzdWIiOiJ1c2VyLTEwMjQiLCJpYXQiOjE3MDQwNjcyMDAsImV4cCI6MTcwNDA2ODEwMH0{"sub":"user-1024","iat":1704067200,"exp":1704068100}7153
    Signature5YZB1gnh7IFicIbrPtT-mJoFb3uuYFcYTk84hPIA7RoHMAC-SHA256 value (not JSON)4332

    Every 3 bytes become 4 characters, so a Base64url part is about one third longer than the original JSON. The length of the signature part depends on the algorithm: HS256 gives 32 bytes (43 characters), RS256 gives the size of the RSA key (a 2048-bit key means 256 bytes, 342 characters) and ES256 gives 64 bytes (86 characters). If there are five parts, the token is an encrypted JWE (RFC 7516). The header of a JWE is readable, but the other four parts cannot be decoded without the recipient's key.

    Common claims and what to check

    Each item in the payload is called a claim. The seven claims registered by RFC 7519 and the names defined by OpenID Connect have fixed meanings, and any other name is a value the issuing service defines on its own (a Private Claim). The "What to check" column in the table lists what a server that receives the token has to do.

    Registered claims and the recipient's checks
    ClaimMeaningWhat to check
    issIssuerIt must equal the trusted issuer value character for character. A single trailing / makes it a different value.
    subSubject (user ID)It is unique only within the issuer, so combine it with iss to tell users apart.
    audAudienceA string or an array. Reject the token if your own name is not in it (RFC 7519 4.1.3).
    expExpiration timeThe token is expired when the current time is equal to or later than exp. You may allow a tolerance of a few minutes at most for clock differences.
    nbfNot beforeIf the current time is earlier than nbf, the token must not be accepted yet.
    iatIssued atUsed to see how old the token is. It does not by itself decide expiry.
    jtiToken IDIf you record the jti values already used, you can stop the same token from being reused.
    nonceRequest check value (OIDC)It must equal the value sent in the login request. If it differs, the token belongs to a different login.
    azpApp that received the token (OIDC)If present, check that it equals your own client_id.
    scopePermission scopeA list separated by spaces. Check that it contains the scope the requested action needs.

    Reading exp, nbf and iat, and the clock tolerance

    All three times are seconds counted from 00:00 UTC on January 1, 1970 (NumericDate in RFC 7519). Written in New York time, the same moment is 5 hours earlier in winter and 4 hours earlier during daylight saving time. A value written in milliseconds has 13 digits, and read as seconds it points tens of thousands of years ahead, so the token effectively never ends. The tool adds a warning when it finds such a value.

    Second values and their times
    ValueUTCNew York (ET)Note
    17040672002024-01-01 00:00:002023-12-31 19:00:00 (UTC−05:00)iat of the example token above
    17040681002024-01-01 00:15:002023-12-31 19:15:00 (UTC−05:00)exp of the example token, lifetime 900 seconds = 15 minutes
    20000000002033-05-18 03:33:202033-05-17 23:33:20 (UTC−04:00, DST)A ten-digit seconds value
    1704067200000(read as seconds: year 55969)-Wrongly written in milliseconds, must be divided by 1000

    The clock of your server and the clock of the issuing server can differ by anything from a few seconds to a few minutes. RFC 7519 says that when checking exp and nbf you may allow a small tolerance, "usually no more than a few minutes". The actual default differs by library, so the same token can be accepted by one server and rejected by another.

    Default clock tolerance by library (based on source code, October 2026)
    LibrarySetting nameDefault
    PyJWT (Python)leeway0 s
    jsonwebtoken (Node.js)clockTolerance0 s
    Spring Security (Java)JwtTimestampValidator clockSkew60 s
    Microsoft.IdentityModel (.NET)TokenValidationParameters.ClockSkew5 min (300 s)

    The tool's verdict follows jsonwebtoken. If the current time (rounded down to the second) is equal to or later than exp plus the tolerance, the token is expired, and if nbf is later than the current time plus the tolerance, it is not valid yet. When the expiry time has passed but is still within the tolerance, the time checkpoint passes and the remaining margin is shown.

    Checking the signature: the key each algorithm needs

    The alg in the header is only the name of the method the token says it was signed with. The recipient must not simply trust it, so a server should decide the algorithms it allows in advance and reject anything else (RFC 8725 3.1). The tool tells you which kind of key fits alg, and gives the reason when you enter a key that does not fit.

    Keys used for checking, by algorithm family
    algKey used to checkAccepted formatsRule
    HS256·HS384·HS512The same secret as the creatorPlain text, Base64 value, JWK (kty oct)The key must be at least as long as the hash (256 bits for HS256, RFC 7518 3.2)
    RS256·RS384·RS512RSA public keyPEM public key, PKCS#1, X.509 certificate, JWK, JWKSAt least 2048 bits (RFC 7518 3.3)
    PS256·PS384·PS512RSA public keySame as the RS familyRSA-PSS, salt length = hash length (RFC 7518 3.5)
    ES256P-256 public keyPEM, certificate, JWK (kty EC), JWKSThe signature is R and S joined, 64 bytes (RFC 7518 3.4)
    ES384P-384 public keySame as ES256Signature of 96 bytes
    ES512P-521 public keySame as ES256Signature of 132 bytes (the curve name is P-521)
    EdDSA·Ed25519Ed25519 public keyPEM, JWK (kty OKP)RFC 9864 (October 2025) says to use the name Ed25519 instead of EdDSA

    If you enter a private key, the tool extracts the public key and checks with it, but a public key is all that checking needs. A line break is often added at the end when a secret is copied, so if the secret as entered does not match but matches with the leading and trailing spaces removed, the tool says so. An ES token whose signature is in DER format (starting with 0x30) was built wrongly by another library, so the tool marks that cause separately.

    Why the checkpoints follow the order a server uses

    Section 7.2 of RFC 7519 describes the order for receiving a JWT: split the parts, decode the Base64url and JSON, and check the signature. If any step fails, the token must be rejected. On top of that, RFC 8725 requires checking that the signing key belongs to the issuer when iss is present (3.8), and, when one issuer serves several applications, rejecting a token whose aud is missing or not yours (3.9). The tool's four checkpoints follow this order exactly and write the reason for the first checkpoint that stops the token on the verdict line. While the signature has not been checked, the other checkpoints stay marked "not checked yet" even if they pass.

    Whether the permission is right, whether the session has already logged out, and whether the same jti was used again cannot be known from the token alone. A server checks those conditions with its own records and settings, so passing all four checkpoints only means that "the conditions of the token itself are met".

    Editing JSON and signing again

    When you change the header or payload under "Edit JSON", the tool builds a new token and puts it in the token field. If the signature check section has an HS secret or a private key for RS, PS, ES or Ed25519 (PKCS#8, PKCS#1, an EC private key, or a JWK with d), the token is signed again with that key. If there is only a public key or no key, the original signature is attached unchanged, so the signature checkpoint turns to a mismatch. The "Edited token" example is exactly this case. The role value was changed from user to admin while the signature stayed the same, so checking with the secret exposes it immediately.

    The buttons "Set iat to now and exp to 15 min, 1 hr or 1 day" change the times of a test token in one step. If nbf is present, it is set to now as well. The edited JSON only has its spaces removed to make one line, so the key order and number notation stay as you wrote them.

    Common mistakes and known attacks

    • A server that accepts alg none: anyone can create a token without a signature. Some libraries even accepted None and NONE, which differ only in case, so block it with an allowed list (RFC 8725 2.1).
    • Swapping an RS256 token for HS256: the attacker changes alg to HS256 and signs using the server's public key as the HMAC secret. Using one key for one algorithm only prevents it. The tool reports this form when you enter a public key for an HS token.
    • A secret that is easy to remember: with just one HS256 token in hand, the secret can be found by a dictionary attack. Generate the secret randomly (RFC 8725 3.5) and make it at least as long as the hash output, which is 32 bytes for HS256 (RFC 7518 3.2).
    • A server that does not check aud: it accepts a token the same issuer gave to another service. Using an ID token for API access is a mistake that has to be blocked for the same reason.
    • Key lookup that uses kid or jku as is: if you put kid straight into a file path or SQL, or fetch keys from the jku address in the header, the check ends up using a key the attacker chose (RFC 8725 3.10).
    • Personal data in the payload: a signed JWT is not encrypted. If you put an email or phone number in it, it can be read in any log or browser the token passes through.
    • Extra characters from copying: if Bearer, quotes or line breaks come along, the server cannot read the token. The tool removes these characters before reading and tells you what it removed.

    Limits and cautions

    • For a JWE (five parts), the tool reads only the header and does not decrypt. It also does not read nested JWTs, tokens with b64 set to false (RFC 7797) or JWS in JSON serialization.
    • Signature checking uses the browser's Web Crypto. ES256K and Ed448 cannot be checked, and on older browsers that do not support Ed25519, the tool says it cannot check.
    • It does not fetch keys from a jku or x5u address or from a provider's jwks_uri. You have to paste the public key yourself, a choice made so that the token is never sent outside.
    • The time verdict is based on this device's clock. If the device clock is wrong, the time left and the verdict are wrong by the same amount.
    • Even when all four checkpoints pass, only the server knows about permissions, logout and reuse. Avoid pasting production secrets and real user tokens where you can, and check with test keys and tokens.

    Basis: the JWT, JWS, JWE, JWK and JWA rules come from RFC 7519, 7515, 7516, 7517 and 7518, the security recommendations from RFC 8725, the Ed25519 name from RFC 9864, ID token claims from OpenID Connect Core 1.0, and the default tolerances from each library's source code, checked on October 22, 2026. The tokens and times in the tables were confirmed to give the same values in this tool and in Python PyJWT 2.13.

    Sources

    Frequently asked questions

    Can I tell whether a JWT is valid just by decoding it?

    No. The header and payload are Base64url, so anyone can decode them, and seeing the content only means the format is right. To know whether it is valid you must also check that the signature matches, that exp has not passed, and that iss and aud are the expected values. The four checkpoints in the tool above follow exactly this order.

    Is a JWT payload encrypted?

    A signed JWT (two dots, three parts) is not encrypted. The signature only guarantees the content was not changed and does not hide it. Do not put values others must not see, such as an email or phone number, in the payload, or use an encrypted JWE instead.

    Why do I get a 401 when exp has not passed yet?

    The token is rejected when the signing key was rotated and no public key matches the kid, when aud differs from the API's name, or when iss differs from the server configuration by even one character. If the server clock is fast, a token close to expiry may be judged expired early. If the server revoked the token separately, for example after a logout, you cannot tell from the token alone.

    I entered the HS256 secret but get a signature mismatch.

    First check whether the secret in the server configuration is plain text or a Base64 value, and switch between 'Plain text' and 'Base64 value'. The tool removes a line break added by copying and checks again. If it still fails, the key belongs to another environment (development or production), or the header or payload was changed after signing.

    Where do I get the public key to verify an RS256 token?

    For an OpenID Connect provider, the list of public keys (JWKS) is at the jwks_uri in the document at the issuer address plus /.well-known/openid-configuration. Paste that JSON as is and the tool picks the key with the same kid as the token header and checks with it. You can also enter a PEM public key or an X.509 certificate.

    Is it safe to paste a token here?

    The token and key are processed only in this browser and are never sent or stored. Still, a production access token is a working key until it expires, so be careful when you share or capture your screen, and check with a test token where you can.

    What unit is the exp number in?

    Seconds counted from 00:00 UTC on January 1, 1970. 1704067200 is 00:00 UTC on January 1, 2024, which is 7 p.m. on December 31, 2023 in New York. A 13-digit value was wrongly written in milliseconds, and read as seconds it points tens of thousands of years ahead, so divide it by 1000.

    What is a token with four dots (five parts)?

    It is an encrypted JWE. Only the first part, the header, can be read, and the rest must be decrypted with the recipient's key before the content is visible. This tool shows only the alg and enc of the JWE header and the byte count of each part.