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

  1. 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
  2. Refresh the expired STS session (re-assume the role) and retry
  3. 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

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

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/83b4d0a0677acf1f. Report an issue: GitHub.