alibaba/nacos · error · AccessException

token expired!

Error message

token expired!

What it means

Thrown by NacosSignatureAlgorithm.verify() as an AccessException when the JWT passed signature verification but its exp (expiration) claim is in the past relative to the current wall-clock time (compared in epoch seconds). The token is valid in structure and signature but has expired.

Source

Thrown at plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/jwt/NacosSignatureAlgorithm.java:143

     * @return object for payload
     * @throws AccessException access exception
     */
    public NacosUser verify(String header, String payload, String signature, Key key)
        throws AccessException {
        Mac macInstance = getMacInstance(key);
        byte[] bytes = macInstance
            .doFinal((header + JWT_SEPERATOR + payload).getBytes(StandardCharsets.US_ASCII));
        if (!URL_BASE64_ENCODER.encodeToString(bytes).equals(signature)) {
            throw new AccessException("Invalid signature");
        }
        NacosJwtPayload nacosJwtPayload =
            JacksonUtils.toObj(URL_BASE64_DECODER.decode(payload), NacosJwtPayload.class);
        if (nacosJwtPayload.getExp() >= TimeUnit.MILLISECONDS
            .toSeconds(System.currentTimeMillis())) {
            return new NacosUser(nacosJwtPayload.getSub());
        }
        
        throw new AccessException("token expired!");
    }
    
    /**
     * get jwt expire time in seconds.
     *
     * @param jwt complete jwt string
     * @param key for signature
     * @return expire time in seconds
     * @throws AccessException access exception
     */
    public static long getExpiredTimeInSeconds(String jwt, Key key) throws AccessException {
        if (StringUtils.isBlank(jwt)) {
            throw new AccessException("user not found!");
        }
        String[] split = jwt.split("\\.");
        if (split.length != JWT_PARTS) {
            throw new AccessException("token invalid!");
        }

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Refresh the token by re-authenticating before the expiry window closes.
  2. Increase token.expire.seconds if the workload legitimately needs longer-lived tokens.
  3. Verify server/client clocks are synchronized (NTP) to avoid false expiries.

Example fix

// before
const token = getTokenFromCache(); // may be hours old
client.callApi({ Authorization: `Bearer ${token}` });
// -> token expired!

// after
if (isExpired(token)) token = await login();
client.callApi({ Authorization: `Bearer ${token}` });
Defensive patterns

Strategy: validation

Validate before calling

String[] parts = jwt.split("\\.");
long exp = JacksonUtils.toObj(
    new String(Base64.getUrlDecoder().decode(parts[1]), StandardCharsets.UTF_8),
    NacosJwtPayload.class).getExp();
long now = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
if (exp < now) {
    throw new AccessException("token expired!");
}

Try / catch

try {
    NacosSignatureAlgorithm.verify(jwt, key);
} catch (AccessException e) {
    if ("token expired!".equals(e.getMessage())) {
        jwt = relogin(); // refresh then retry once
        NacosSignatureAlgorithm.verify(jwt, key);
    }
}

Prevention

When it happens

Trigger: After a successful HMAC match, nacosJwtPayload.getExp() < TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()), so the method throws instead of returning a NacosUser.

Common situations: The token's lifetime elapsed (default 18000s/~5h); client clock skew; a long-running operation that outlived the token; server clock drifted forward.

Understand the failure class

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/5f2de8f60c465d93. Report an issue: GitHub.