{"record":{"id":"75389013ca3d2f69","repo":"alibaba/nacos","slug":"expired-token","errorCode":null,"errorMessage":"expired token","messagePattern":"expired token","errorType":"exception","errorClass":"AccessException","httpStatus":null,"severity":"error","filePath":"plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/token/impl/CachedJwtTokenManager.java","lineNumber":173,"sourceCode":"        tokenMap.putIfAbsent(token,\n            new TokenEntity(token, username, expiredTime, authentication, user));\n    }\n    \n    @Override\n    public NacosUser parseToken(String token) throws AccessException {\n        TokenEntity cached = tokenMap.get(token);\n        if (cached != null) {\n            return cached.getNacosUser();\n        }\n        Authentication authentication = jwtTokenManager.getAuthentication(token);\n        String username = authentication.getName();\n        if (username == null || username.isEmpty()) {\n            throw new AccessException(\"invalid token, username is empty\");\n        }\n        long expiredTime =\n            TimeUnit.SECONDS.toMillis(jwtTokenManager.getExpiredTimeInSeconds(token));\n        if (expiredTime <= System.currentTimeMillis()) {\n            throw new AccessException(\"expired token\");\n        }\n        NacosUser user = jwtTokenManager.parseToken(token);\n        tokenMap.putIfAbsent(token,\n            new TokenEntity(token, username, expiredTime, authentication, user));\n        return user;\n    }\n    \n    public long getTokenTtlInSeconds(String token) throws AccessException {\n        TokenEntity cached = tokenMap.get(token);\n        if (cached != null) {\n            return TimeUnit.MILLISECONDS.toSeconds(\n                cached.getExpiredTimeMills() - System.currentTimeMillis());\n        }\n        return jwtTokenManager.getTokenTtlInSeconds(token);\n    }\n    \n    @Override\n    public long getTokenValidityInSeconds() {","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/token/impl/CachedJwtTokenManager.java#L155-L191","documentation":"After resolving the username, the manager computes the token's expiry from its JWT 'exp' claim; if that time is at or before the current clock it throws AccessException('expired token'). This is the expected, operational auth-expiry path: the token was once valid but its TTL elapsed. The TTL is governed by nacos.plugin.auth.nacos.token.expire.seconds.","triggerScenarios":"A client reuses an access token past its configured expire-seconds window; the token cache was cleared (e.g. by applyTokenConfig cache-clear) forcing a re-parse that now sees exp in the past; clock skew between the issuing node and the parsing node.","commonSituations":"Long-running SDK sessions that never re-login; failover to a node whose clock is ahead; admin clearing the token cache mid-session.","solutions":["Re-authenticate to obtain a fresh token (the SDK should do this automatically via its token-refresh logic).","If caused by clock skew, synchronize node clocks (NTP/chrony) so exp comparisons are consistent.","Optionally raise nacos.plugin.auth.nacos.token.expire.seconds if the TTL is too short for your workload.","Ensure the SDK's token refresh task is enabled and running."],"exampleFix":"// before: stale token reused\nclient.setAccessToken(oldToken); // -> expired token\n\n// after: re-login on expiry\ntry {\n    client.doRequest(...);\n} catch (AccessException e) {\n    if (\"expired token\".equals(e.getMessage())) {\n        client.relogin(); // fetch a fresh token\n        client.doRequest(...);\n    }\n}","handlingStrategy":"retry","validationCode":"// Before relying on a cached token, check its TTL and refresh proactively.\nlong ttl = tokenManager.getTokenTtlInSeconds(token);\nif (ttl <= 0) {\n    // expired (or about to) -> re-authenticate\n    token = login(username, password);\n}","typeGuard":null,"tryCatchPattern":"try {\n    tokenManager.parseToken(token);\n} catch (AccessException e) {\n    if (\"expired token\".equals(e.getMessage())) {\n        token = relogin(); // obtain a fresh token, then retry\n        tokenManager.parseToken(token);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Enable the SDK's token-refresh task so it re-logins before expiry.","Synchronize node clocks via NTP to avoid false expiry from skew.","Set a token TTL that comfortably exceeds your longest request window.","Handle 'expired token' by re-authenticating, not by retrying the same token."],"tags":["auth","token","jwt","expiry"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}