apache/hadoop · error · DelegationTokenIOException
AWS Authentication chain is no longer supplying session secr
Error message
AWS Authentication chain is no longer supplying session secrets
What it means
SessionTokenBinding issues delegation tokens by marshalling the parent authentication chain's currently resolved credentials, and it requires those to be AwsSessionCredentials (access key + secret + session token). If the chain now resolves to non-session credentials, binding throws DelegationTokenIOException 'AWS Authentication chain is no longer supplying session secrets', refusing to mint a session-token identifier from credentials that carry no session component.
Source
Thrown at hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/auth/delegation/SessionTokenBinding.java:382
// this is the normal route: ask for a new STS token
marshalledCredentials = fromSTSCredentials(
client.get()
.requestSessionCredentials(duration, TimeUnit.SECONDS));
} else {
// get a new set of parental session credentials (pick up IAM refresh)
if (!forwardMessageLogged.getAndSet(true)) {
// warn caller on the first -and only the first- use.
LOG.warn("Forwarding existing session credentials to {}"
+ " -duration unknown", getCanonicalUri());
}
origin += " " + CREDENTIALS_CONVERTED_TO_DELEGATION_TOKEN;
final AwsCredentials awsCredentials
= getParentAuthChain().resolveCredentials();
if (awsCredentials instanceof AwsSessionCredentials) {
marshalledCredentials = fromAWSCredentials(
(AwsSessionCredentials) awsCredentials);
} else {
throw new DelegationTokenIOException(
"AWS Authentication chain is no longer supplying session secrets");
}
}
return new SessionTokenIdentifier(getKind(),
getOwnerText(),
renewer,
getCanonicalUri(),
marshalledCredentials,
encryptionSecrets,
origin);
}
@Override
public SessionTokenIdentifier createEmptyIdentifier() {
return new SessionTokenIdentifier();
}
/**View on GitHub (pinned to 2add963021)
Solutions
- Ensure the provider chain resolves to session credentials before token creation: use STS assume-role / web-identity / instance-profile providers and remove or reorder static-key providers that shadow them
- Refresh the expired STS session (re-assume the role) and retry
- If the deployment now uses long-lived keys, switch fs.s3a.delegation.token.binding to S3ATokenBinding instead of SessionTokenBinding
Example fix
<!-- before: static provider wins, chain returns AwsBasicCredentials --> <property><name>fs.s3a.aws.credentials.provider</name> <value>org.apache.hadoop.fs.s3a.auth.SimpleAWSCredentialsProvider</value></property> <!-- after: session-capable provider first for SessionTokenBinding --> <property><name>fs.s3a.aws.credentials.provider</name> <value>com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider</value></property>
Defensive patterns
Strategy: type-guard
Validate before calling
AwsCredentials c = fs.getDelegationTokens() // or your auth chain
.getParentAuthChain().resolveCredentials();
if (!(c instanceof AwsSessionCredentials)) {
throw new IOException("Session DT requested but chain supplies "
+ c.getClass().getSimpleName() + " without session secrets");
} Type guard
static boolean hasSessionSecrets(AwsCredentials c) {
return c instanceof AwsSessionCredentials
&& ((AwsSessionCredentials) c).sessionToken() != null
&& !((AwsSessionCredentials) c).sessionToken().isEmpty();
} Try / catch
try {
Token<AbstractS3ATokenIdentifier> dt = fs.getDelegationToken(renewer);
} catch (DelegationTokenIOException e) {
if (e.getMessage().contains("no longer supplying session secrets")) {
// STS session expired or provider order changed: refresh creds, then retry once
refreshStsSession();
dt = fs.getDelegationToken(renewer);
} else {
throw e;
}
} Prevention
- Order providers so session-capable sources (STS/instance profile) win when SessionTokenBinding is used
- Refresh STS sessions on a schedule well inside their lifetime
- If moving to long-lived keys, switch the binding to S3ATokenBinding
When it happens
Trigger: SessionTokenBinding.createTokenIdentifier calls getParentAuthChain().resolveCredentials() and the result is not an instanceof AwsSessionCredentials. Happens when an STS/assumed-role session expired or provider order changed so a static-key or instance-profile provider now wins at token creation or renewal time.
Common situations: STS temporary credentials expiring mid-job right when a delegation token is requested; adding fs.s3a.aws.credentials.provider entries that put SimpleAWSCredentialsProvider ahead of session sources; switching from role-based to static keys without changing the binding away from SessionTokenBinding.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Delegation token is wrong class; expected a token identifier
- No URI in {this}
- Incompatible EncryptionSecrets version: {versionId}
- No AWS credential providers created by Delegation Token Bind
- Decoding S3A token {cause}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/83b4d0a0677acf1f.
Report an issue: GitHub.