New from Septim Labs: $99 Septim Audit — 10-agent teardown of your SaaS in 48h. | Tip the founder ♥ | All 5 founder products — $169
jwtauthenticationsecurity2026-04-10 · 7 min read

JWT Tokens Explained: How to Decode and Debug Them

JSON Web Tokens (JWTs) are everywhere in modern web development. If you have ever worked with an API that requires authentication, chances are you have encountered a JWT. They are compact, URL-safe tokens that carry claims between two parties, and understanding how they work is essential for any developer building or consuming authenticated services.

In this guide we will break down exactly what a JWT is, walk through its three-part structure, explain the most common claims, and show you how to decode and debug them when things go wrong.

What Is a JSON Web Token?

A JSON Web Token is an open standard (RFC 7519) that defines a compact, self-contained way to transmit information between parties as a JSON object. The token is digitally signed, which means its contents can be verified and trusted. JWTs are most commonly used for authentication and authorization: after a user logs in, the server issues a JWT that the client includes with every subsequent request to prove its identity.

Unlike traditional session-based authentication where the server stores session state, JWTs are stateless. All the information the server needs to validate the request is encoded directly in the token. This makes JWTs ideal for distributed systems, microservices, and single-page applications where you need to decode a JWT token on the client or across multiple services.

The Three Parts of a JWT

Every JWT consists of three Base64URL-encoded parts separated by dots. When you look at a raw token, it follows the pattern header.payload.signature. Each part serves a distinct purpose.

1. Header

The header typically contains two fields: the type of token (which is JWT) and the signing algorithm being used, such as HS256 (HMAC SHA-256) or RS256 (RSA SHA-256). When you decode a JWT token, the header tells you how the signature was created and how to verify it.

A typical header looks like {"alg": "HS256", "typ": "JWT"}. This is then Base64URL-encoded to form the first segment of the token string.

2. Payload (Claims)

The payload is the most important part of the token. It contains claims, which are statements about the user and additional metadata. Claims are where the actual data lives, and understanding them is critical when you need to debug authentication issues or decode a JWT token to inspect its contents.

There are three types of claims: registered claims defined in the JWT specification, public claims defined by the developer community, and private claims that are custom to your application.

3. Signature

The signature is created by taking the encoded header, the encoded payload, a secret key, and the algorithm specified in the header. For HS256, this means computing HMAC-SHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret).

The signature ensures that the token has not been tampered with. If anyone modifies the header or payload, the signature will no longer match, and the server will reject the token. Note that the payload is encoded, not encrypted. Anyone can decode a JWT and read its contents, but only someone with the secret key can create a valid signature.

Common JWT Claims Explained

The JWT specification defines several registered claims. While none are mandatory, they are widely adopted and you will encounter them in almost every token:

  • iss (Issuer) — identifies the principal that issued the token, such as your authentication server or identity provider.
  • sub (Subject) — identifies the subject of the token, typically the user ID or account identifier.
  • aud (Audience) — identifies the recipients the token is intended for. Your API should reject tokens with an unexpected audience value.
  • exp (Expiration Time) — a Unix timestamp after which the token must not be accepted. This is one of the most common sources of authentication bugs.
  • nbf (Not Before) — a Unix timestamp before which the token must not be accepted. Useful for tokens that should only become valid at a future time.
  • iat (Issued At) — a Unix timestamp indicating when the token was created. Useful for determining the age of a token.
  • jti (JWT ID) — a unique identifier for the token, which can be used to prevent the token from being replayed.

In addition to these registered claims, most tokens include custom claims such as email, role, or permissions that are specific to the application.

How to Decode a JWT Token

Because the header and payload are simply Base64URL-encoded (not encrypted), you can decode any JWT without knowing the secret key. This is incredibly useful for debugging. When an API returns a 401 or 403 error, the first thing you should do is decode the JWT token and inspect its claims.

You can decode a JWT manually by splitting it on the dot characters and running each part through a Base64 decoder. However, the fastest approach is to use a dedicated jwt decoder tool that parses everything for you, highlights expiration status, and displays the claims in a readable format.

Try our free JWT Decoder — paste any token and instantly see the decoded header, payload, and expiration status. No data is sent to any server; everything runs directly in your browser.

Debugging Common JWT Issues

When working with JWTs, there are a handful of problems that come up over and over. Here are the most common issues and how to solve them:

Token expired. Check the exp claim. If the current Unix timestamp is greater than exp, the token is no longer valid. Make sure your server clocks are synchronized and that your token refresh logic is working correctly.

Invalid signature. This usually means the token was signed with a different key than the one the server is using to verify it. Double-check that the signing secret or public key matches across your services. In microservice architectures, key rotation issues are a frequent cause.

Wrong audience or issuer. If your API validates the aud or iss claims, make sure the token was issued by the expected identity provider and is intended for your specific service.

Clock skew. In distributed systems, server clocks can drift apart. A token that looks expired on one server may still be valid on another. Most JWT libraries accept a small leeway (typically 30 to 60 seconds) to account for this.

JWT Security Best Practices

JWTs are powerful, but using them incorrectly can introduce serious security vulnerabilities. Follow these best practices to keep your authentication system secure:

  • Always verify the signature. Never trust the contents of a JWT without validating its signature first. This is the entire point of the signature.
  • Use strong signing algorithms. Prefer RS256 or ES256 for production systems. Avoid none as the algorithm, which disables signature verification entirely.
  • Set short expiration times. Access tokens should expire in minutes, not hours or days. Use refresh tokens to issue new access tokens when needed.
  • Do not store sensitive data in the payload. Remember that JWTs are encoded, not encrypted. Anyone who intercepts the token can read its contents. Never include passwords, credit card numbers, or other secrets in the payload.
  • Validate all claims. Check exp, iss, aud, and any other claims your application relies on. Failing to validate claims can allow token misuse across services.
  • Use HTTPS exclusively. JWTs sent over unencrypted connections can be intercepted. Always use TLS to protect tokens in transit.
  • Store tokens securely on the client. Avoid storing JWTs in localStorage where they are vulnerable to XSS attacks. Consider using httpOnly cookies instead.

When to Use JWTs (and When Not To)

JWTs are a great fit for stateless authentication in APIs, single sign-on (SSO) across multiple services, and passing claims between microservices. Their self-contained nature means you do not need to hit a database on every request to validate the user.

However, JWTs are not ideal for every situation. If you need the ability to revoke individual sessions immediately (such as when a user changes their password), pure JWT-based authentication makes this difficult because tokens remain valid until they expire. In those cases, consider combining JWTs with a server-side revocation list or using shorter expiration times with token refresh.

Start Decoding JWTs Now

Understanding the structure of a JSON Web Token is the first step to building and debugging secure authentication. Whether you are troubleshooting a 401 error, inspecting token claims, or verifying expiration timestamps, having a reliable jwt decoder at hand saves significant time.

Try our free JWT Decoder to paste any token and instantly see its decoded header, payload, and signature status. It runs entirely in your browser with no data sent to external servers.

Try Septim Forge Pro

22 developer tools, all running in your browser. Pro unlocks advanced tools for a one-time $9.

Get Pro — $9 Lifetime