apache/hadoop · error · DelegationTokenIOException

No AWS credential providers created by Delegation Token Bind

Error message

No AWS credential providers created by Delegation Token Binding {tokenBindingName}

What it means

After S3ADelegationTokens binds to a token or deploys unbonded, it asserts that the active delegation-token binding produced at least one AWSCredentialProvider for the filesystem to authenticate with. Zero providers means the binding deployed but supplied nothing usable, which would otherwise surface later as an obscure authentication failure, so it fails fast naming the binding.

Source

Thrown at hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/auth/delegation/S3ADelegationTokens.java:284

   *
   * This means after this call (and only after) the token operations
   * can be invoked.
   *
   * This method is called from {@link #serviceStart()}, so a check on
   * the service state can be used to check things; the state model
   * prevents re-entrant calls.
   * @throws IOException selection/extraction/validation failure.
   */
  private void bindToAnyDelegationToken() throws IOException {
    checkState(!bindingInfo.isPresent(), E_ALREADY_DEPLOYED);
    Token<AbstractS3ATokenIdentifier> token = selectTokenFromFSOwner();
    if (token != null) {
      bindToDelegationToken(token);
    } else {
      deployUnbonded();
    }
    if (getCredentialProviders().size() == 0) {
      throw new DelegationTokenIOException("No AWS credential providers"
          + " created by Delegation Token Binding "
          + tokenBinding.getName());
    }
  }

  /**
   * This is a test-only back door which resets the state and binds to
   * a token again.
   * This allows an instance of this class to be bonded to a DT after being
   * started, so avoids the need to have the token in the current user
   * credentials. It is package scoped so as to only be usable in tests
   * in the same package.
   *
   * Yes, this is ugly, but there is no obvious/easy way to test token
   * binding without Kerberos getting involved.
   * @param token token to decode and bind to.
   * @throws IOException selection/extraction/validation failure.
   */

View on GitHub (pinned to 2add963021)

Solutions

  1. Check fs.s3a.delegation.token.binding: use a standard binding (org.apache.hadoop.fs.s3a.auth.delegation.S3ATokenBinding or SessionTokenBinding) unless you really need a custom one
  2. If the binding is custom, fix its deploy/bind path to return at least one AWSCredentialProvider
  3. Verify the binding class version matches the hadoop-aws version on the classpath
Defensive patterns

Strategy: try-catch

Validate before calling

String binding = conf.getTrimmed("fs.s3a.delegation.token.binding", "");
Set<String> known = Set.of(
    "org.apache.hadoop.fs.s3a.auth.delegation.S3ATokenBinding",
    "org.apache.hadoop.fs.s3a.auth.delegation.SessionTokenBinding");
if (!binding.isEmpty() && !known.contains(binding)) {
  LOG.warn("Non-standard DT binding {} - verify it deploys credential providers", binding);
}

Try / catch

try {
  delegationTokens.start();
} catch (DelegationTokenIOException e) {
  if (e.getMessage().contains("No AWS credential providers")) {
    // binding deployed but produced nothing: fix or unset fs.s3a.delegation.token.binding
    conf.unset("fs.s3a.delegation.token.binding");
    retryWithoutDelegationTokens(); // explicit fallback, not silent
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: bindToAnyDelegationToken completes and getCredentialProviders().size() == 0. Typical with a custom or third-party token binding whose bindToDelegationToken/deployUnbonded implementation returns an empty provider list, or a binding version mismatch where the provider-creation path is skipped.

Common situations: Custom delegation-token bindings under development that forget to add providers; misconfigured binding class that deploys but does not wire credentials; upgrading a custom binding without updating its integration.

Related errors


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