apache/hadoop · error · IOException
Delegation Token can be issued only with kerberos or web aut
Error message
Delegation Token can be issued only with kerberos or web authentication
What it means
RouterSecurityManager.getDelegationToken refuses to issue a delegation token when isAllowedDelegationTokenOp() returns false: security is enabled (UserGroupInformation.isSecurityEnabled()) but the connection's authentication method is not KERBEROS, KERBEROS_SSL, or CERTIFICATE. getConnectionAuthenticationMethod() unwraps PROXY to inspect the real user's method. Despite the message wording ('kerberos or web authentication'), the code only accepts the strong auth methods — the point is that a weakly-authenticated (e.g. SIMPLE or DIGEST/token-authenticated) connection may not mint new tokens.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/security/RouterSecurityManager.java:133
}
return true;
}
/**
* @param renewer Renewer information
* @return delegation token
* @throws IOException on error
*/
public Token<DelegationTokenIdentifier> getDelegationToken(Text renewer)
throws IOException {
LOG.debug("Generate delegation token with renewer " + renewer);
final String operationName = "getDelegationToken";
boolean success = false;
String tokenId = "";
Token<DelegationTokenIdentifier> token;
try {
if (!isAllowedDelegationTokenOp()) {
throw new IOException(
"Delegation Token can be issued only " +
"with kerberos or web authentication");
}
if (dtSecretManager == null || !dtSecretManager.isRunning()) {
LOG.warn("trying to get DT with no secret manager running");
return null;
}
UserGroupInformation ugi = getRemoteUser();
String user = ugi.getUserName();
Text owner = new Text(user);
Text realUser = null;
if (ugi.getRealUser() != null) {
realUser = new Text(ugi.getRealUser().getUserName());
}
DelegationTokenIdentifier dtId = new DelegationTokenIdentifier(owner,
renewer, realUser);
token = new Token<DelegationTokenIdentifier>(
dtId, dtSecretManager);View on GitHub (pinned to 2add963021)
Solutions
- Authenticate with kerberos before requesting the token: kinit, or UserGroupInformation.loginUserFromKeytab, so the RPC connection carries KERBEROS authentication.
- Never call getDelegationToken on a session already authenticated by a delegation token — fetch the token once via kerberos, then renew/cancel it as needed.
- If using a proxy user, make sure the real (underlying) user authenticated with kerberos, not SIMPLE.
- Align hadoop.security.authentication=kerberos in the client's core-site.xml with the secured Router.
Example fix
// before: SIMPLE-authenticated UGI on a secured cluster
FileSystem fs = FileSystem.get(conf);
Token<?> t = fs.getDelegationToken("yarn"); // throws
// after: kerberos login first, then fetch
UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab("hdfs/_HOST@REALM", "/etc/security/keytabs/hdfs.keytab");
FileSystem fs = UserGroupInformation.getLoginUser().doAs((PrivilegedExceptionAction<FileSystem>) () -> FileSystem.get(conf));
Token<?> t = fs.getDelegationToken("yarn"); Defensive patterns
Strategy: validation
Validate before calling
// Check the connection's auth method BEFORE requesting a token
UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
UserGroupInformation.AuthenticationMethod auth = ugi.getAuthenticationMethod();
if (auth == UserGroupInformation.AuthenticationMethod.PROXY && ugi.getRealUser() != null) {
auth = ugi.getRealUser().getAuthenticationMethod();
}
if (UserGroupInformation.isSecurityEnabled()
&& auth != UserGroupInformation.AuthenticationMethod.KERBEROS) {
throw new IllegalStateException(
"getDelegationToken requires kerberos; current auth=" + auth);
} Try / catch
try {
return fs.getDelegationToken(renewer);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().contains(
"Delegation Token can be issued only")) {
throw new SecurityException("Re-authenticate with kerberos (kinit) before fetching a delegation token", e);
}
throw e;
} Prevention
- Always kinit / loginUserFromKeytab in the entrypoint that fetches DTs; make it a startup assertion.
- Never chain token-from-token: cache the first kerberos-fetched DT for the job instead of re-fetching from a DIGEST session.
- Add a pre-flight auth check (as above) in job launchers so the failure is actionable rather than deep in HDFS.
When it happens
Trigger: Calling getDelegationToken on a secured cluster without a kerberos-authenticated connection: client never did kinit/loginUserFromKeytab; the client authenticated with an existing delegation token (DIGEST) and tries to mint another token from it; a proxy user whose real user is SIMPLE-authenticated; client-side config says simple while the Router requires kerberos.
Common situations: Oozie/Spark/Hive workflow that fetchs a DT from a non-kerberos context; developer testing against a secured router with an unauthenticated FileSystem; tooling that connects via WebHDFS without SPNEGO; proxy-user setups where the real user lost kerberos.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Delegation Token can be renewed only with kerberos or web au
- Failed to create SecretManager
- Fetch of delegation token failed
- Security enabled but user not authenticated by filter
- {} parameter is not null.
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/1ac6adbfef546898.
Report an issue: GitHub.