{"record":{"id":"6cd80fdff496f0d0","repo":"apache/druid","slug":"authenticationtoken-expired","errorCode":null,"errorMessage":"AuthenticationToken expired","messagePattern":"AuthenticationToken expired","errorType":"exception","errorClass":"AuthenticationException","httpStatus":401,"severity":"warning","filePath":"extensions-core/druid-kerberos/src/main/java/org/apache/druid/security/kerberos/KerberosAuthenticator.java","lineNumber":207,"sourceCode":"            if (cookie.getName().equals(AuthenticatedURL.AUTH_COOKIE)) {\n              tokenStr = cookie.getValue();\n              try {\n                tokenStr = mySigner.verifyAndExtract(tokenStr);\n              }\n              catch (SignerException ex) {\n                throw new AuthenticationException(ex);\n              }\n              break;\n            }\n          }\n        }\n        if (tokenStr != null) {\n          token = AuthenticationToken.parse(tokenStr);\n          if (!token.getType().equals(getAuthenticationHandler().getType())) {\n            throw new AuthenticationException(\"Invalid AuthenticationToken type\");\n          }\n          if (token.isExpired()) {\n            throw new AuthenticationException(\"AuthenticationToken expired\");\n          }\n        }\n        return token;\n      }\n\n      @Override\n      public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)\n          throws IOException, ServletException\n      {\n        // If there's already an auth result, then we have authenticated already, skip this.\n        if (request.getAttribute(AuthConfig.DRUID_AUTHENTICATION_RESULT) != null) {\n          filterChain.doFilter(request, response);\n          return;\n        }\n\n        // In the hadoop-auth 2.7.3 code that this was adapted from, the login would've occurred during init() of\n        // the AuthenticationFilter via `initializeAuthHandler(authHandlerClassName, filterConfig)`.\n        // Since we co-exist with other authentication schemes, don't login until we've checked that","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/druid-kerberos/src/main/java/org/apache/druid/security/kerberos/KerberosAuthenticator.java#L189-L225","documentation":"getToken() rejects an AuthenticationToken whose expiry timestamp has passed (token.isExpired()). The kerberos-authenticated session cookie is no longer valid and the user must renegotiate SPNEGO to get a new token.","triggerScenarios":"doFilterSuper -> getToken parses a valid-type token whose validity time is in the past, e.g. a browser session left open longer than the configured authentication session lifetime.","commonSituations":"Long-lived browser tabs after the cookie TTL expired; very short druid.auth.authenticationSessionMillis; clocks skewed between issuing node and verifying node making valid tokens appear expired.","solutions":["Re-authenticate (re-run kinit / reload the page to trigger SPNEGO renegotiation)","Increase druid.auth.authenticationSessionMillis if sessions are expiring too quickly","Synchronize clocks across the cluster (NTP) if skew is causing premature expiry"],"exampleFix":"// before\nprops.setProperty(\"druid.auth.authenticationSessionMillis\", \"900000\"); // 15 min, too short\n// after\nprops.setProperty(\"druid.auth.authenticationSessionMillis\", \"3600000\"); // 1 hour","handlingStrategy":"try-catch","validationCode":"// client-side: check stored token expiry before reusing the cookie\nboolean expired = tokenExpiryMillis > 0 && System.currentTimeMillis() > tokenExpiryMillis;","typeGuard":null,"tryCatchPattern":"try {\n  filter.doFilter(req, res, chain);\n} catch (AuthenticationException e) {\n  if (\"AuthenticationToken expired\".equals(e.getMessage())) {\n    res.setHeader(\"WWW-Authenticate\", \"Negotiate\"); res.sendError(401); // re-run SPNEGO\n  }\n}","preventionTips":["Set druid.auth.authenticationSessionMillis long enough for expected user sessions","Synchronize clocks with NTP on all Druid nodes","Handle 401/Negotiate challenges in HTTP clients to auto re-authenticate"],"tags":["kerberos","token","session-expired"],"backgroundTag":"jwt-token-expired","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}