{"record":{"id":"880b1fb910ab77ed","repo":"apache/hadoop","slug":"delegation-token-can-be-renewed-only-with-kerberos-880b1f","errorCode":null,"errorMessage":"Delegation Token can be renewed only with kerberos or web authentication","messagePattern":"Delegation Token can be renewed only with kerberos or web authentication","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/security/RouterSecurityManager.java","lineNumber":175,"sourceCode":"    return token;\n  }\n\n  /**\n   * @param token token to renew\n   * @return new expiryTime of the token\n   * @throws SecretManager.InvalidToken if {@code token} is invalid\n   * @throws IOException on errors\n   */\n  public long renewDelegationToken(Token<DelegationTokenIdentifier> token)\n          throws SecretManager.InvalidToken, IOException {\n    LOG.debug(\"Renew delegation token\");\n    final String operationName = \"renewDelegationToken\";\n    boolean success = false;\n    String tokenId = \"\";\n    long expiryTime;\n    try {\n      if (!isAllowedDelegationTokenOp()) {\n        throw new IOException(\n            \"Delegation Token can be renewed only \" +\n                \"with kerberos or web authentication\");\n      }\n      String renewer = getRemoteUser().getShortUserName();\n      expiryTime = dtSecretManager.renewToken(token, renewer);\n      final DelegationTokenIdentifier id = DFSUtil.decodeDelegationToken(token);\n      tokenId = id.toStringStable();\n      success = true;\n    } catch (AccessControlException ace) {\n      final DelegationTokenIdentifier id = DFSUtil.decodeDelegationToken(token);\n      tokenId = id.toStringStable();\n      throw ace;\n    } finally {\n      logAuditEvent(success, operationName, tokenId);\n    }\n    return expiryTime;\n  }\n","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/security/RouterSecurityManager.java#L157-L193","documentation":"RouterSecurityManager.renewDelegationToken applies the same guard as token issuance: isAllowedDelegationTokenOp() must be true, i.e. security enabled and the connection authenticated as KERBEROS, KERBEROS_SSL, or CERTIFICATE (PROXY unwrapped to its real user). A token cannot be renewed over a weakly-authenticated connection; the IOException aborts the renew before dtSecretManager.renewToken is reached.","triggerScenarios":"Calling renewDelegationToken without kerberos: client session established with a delegation token (DIGEST) instead of kerberos; unauthenticated (SIMPLE) client on a secured router; proxy user whose real user is not kerberos-authenticated.","commonSituations":"Long-running job tries to renew its own DT using the DT-authenticated FileSystem; cron/renewer service forgot to kinit; mixing secured router with a client whose core-site still says simple.","solutions":["Run the renewer under kerberos: kinit or UserGroupInformation.loginUserFromKeytab before renewDelegationToken, so the connection is KERBEROS-authenticated.","Renew tokens from the kerberos-authenticated job client (as designed), not from a session that only holds the delegation token.","Verify proxy real-user authentication is kerberos when renewing on behalf of another user.","Check that the Router's dtSecretManager is running (the next guard logs 'trying to get DT with no secret manager running') — fix dfs.federation.router.delegation-token.driver-class if so."],"exampleFix":"// before: renewing over a token-authenticated (DIGEST) session\nfs.renewDelegationToken(token); // throws\n\n// after: renew from a kerberos-authenticated context\nUserGroupInformation.loginUserFromKeytab(\"renewer@REALM\", \"/etc/security/keytabs/renewer.keytab\");\nUserGroupInformation.getLoginUser().doAs((PrivilegedExceptionAction<Long>) () -> token.renew(conf));","handlingStrategy":"validation","validationCode":"// Renewal must come from a kerberos-authenticated context\nUserGroupInformation ugi = UserGroupInformation.getLoginUser();\nif (UserGroupInformation.isSecurityEnabled()\n    && ugi.getAuthenticationMethod() != UserGroupInformation.AuthenticationMethod.KERBEROS) {\n  throw new IllegalStateException(\"Token renewal requires kerberos auth; re-kinit\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  long expiry = token.renew(conf);\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Delegation Token can be renewed only\")) {\n    // re-establish kerberos and retry once\n    UserGroupInformation.loginUserFromKeytab(principal, keytab);\n    expiry = token.renew(conf);\n  } else {\n    throw e;\n  }\n}","preventionTips":["Run token renewers (job long-keepers) under a keytab with auto-relogin via UserGroupInformation.checkTGTAndReloginFromKeytab before each renew cycle.","Do not renew from the DT-authenticated task JVM; centralize renewal in the kerberos-authenticated client.","Alert on renewal failures separately from other IOExceptions so auth regressions are visible."],"tags":["hdfs","router-based-federation","security","delegation-token","kerberos","authentication"],"backgroundTag":"kerberos-authentication-required","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}