Encrypt Online
Theme

Encoding & Transport · Field note

JWT claim debugging in practice: exp, nbf, iat, iss, aud, and clock skew

A practical walkthrough of the JWT claims that break most often in staging and production, especially around time and audience validation.

Encrypt Online Editorial Team3 min read
JWT claim debugging in practice: exp, nbf, iat, iss, aud, and clock skew guide cover

Before you start

Decode a small sample first and confirm whether you are changing representation, changing structure, or actually protecting content.

Most production JWT failures are not exotic. They are “wrong audience,” “issuer mismatch,” or “timestamp looks right until you convert it.” That is good news because it means you can debug them with structure instead of guesswork.

The useful habit is to treat claims as policy inputs. A token can be signed perfectly and still be unacceptable in the current context.

In brief

What it is: JWT claims are metadata and constraints carried in the payload, including time windows, issuer identity, and intended audience.

Why it matters: Claims decide whether a token that verifies cryptographically is still acceptable for a specific API, client, or time window.

Watch for: Unix timestamps, local time conversions, and vague audience assumptions create failures that feel random until you inspect them in one time zone and one unit.

Time claims fail in two boring ways

The first boring failure is wrong units. Many systems use Unix seconds; some logs or helper code use milliseconds. Convert the number before you debate whether the token “should” be valid. The second failure is clock skew. A token with a tight nbf or exp window can fail at the edges if one side is a minute or two ahead.

This is where a simple timestamp converter earns its place in a debugging stack. Time bugs are cheap to solve once you can see the same instant in UTC, in local time, and in the original numeric unit.

Issuer and audience are contract checks

iss and aud are not cosmetic. They are how a verifier knows which authority issued the token and which recipient the token was meant for. A token minted for one API should not drift into another just because both use the same identity provider.

Audience problems often come from environment drift: a staging app points at production identity configuration, or a mobile client uses one client ID while the backend expects another. Once you read those values directly, the error usually stops looking cryptic.

Build a repeatable claim review

Read iss, aud, exp, nbf, and iat in that order. Convert time claims. Compare issuer and audience to exact expected values, not rough mental matches. Note any skew allowance your verifier is configured to permit. Then decide whether the token is structurally right, cryptographically right, and contextually acceptable.

That sequence is small enough to memorize and strong enough to use during incidents. It keeps people from arguing about time zones or blaming key rotation when the token was just for the wrong audience all along.

See it in a small example

Notice: Convert the numeric claims before you reason about validity. Seconds, not milliseconds, are the common JWT default.

JSON
{
  "iat": 1775295300,
  "nbf": 1775295300,
  "exp": 1775298900,
  "iss": "https://issuer.example",
  "aud": "api://billing"
}

What to verify

  • Confirm whether the numeric time claim is seconds or milliseconds.
  • Compare iss and aud to exact expected values.
  • Document any clock-skew allowance instead of assuming one exists.

Common questions

Does iat by itself control validity?

Not usually. It records issuance time, but acceptance usually depends on nbf, exp, and verifier policy.

Can a token be unexpired and still be rejected?

Yes. Wrong issuer, wrong audience, or a nbf time in the future are common reasons.

References