apache/hadoop · error · DelegationTokenIOException

Failed to unmarshall token for {canonicalUri}

Error message

Failed to unmarshall token for {canonicalUri}

What it means

If Token.decodeIdentifier() returns null instead of throwing (which Hadoop's Token does when the kind maps to no known identifier factory or decoding yields nothing), S3ADelegationTokens treats it as an unmarshalling failure and throws DelegationTokenIOException 'Failed to unmarshall token for <canonicalUri>' rather than NPE later. The canonical URI in the message identifies which filesystem the unusable token belongs to.

Source

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

      throws IOException {

    checkArgument(token != null, "null token");
    AbstractS3ATokenIdentifier identifier;
    // harden up decode beyond that Token does itself
    try {
      identifier = token.decodeIdentifier();
    } catch (RuntimeException e) {
      Throwable cause = e.getCause();
      if (cause != null) {
        // its a wrapping around class instantiation.
        throw new DelegationTokenIOException("Decoding S3A token " + cause,
            cause);
      } else {
        throw e;
      }
    }
    if (identifier == null) {
      throw new DelegationTokenIOException("Failed to unmarshall token for "
          + getCanonicalUri());
    }
    identifier.validate();
    return identifier;
  }

  /**
   * Return a string for use in building up the User-Agent field, so
   * get into the S3 access logs. Useful for diagnostics.
   * Delegates to {{@link AbstractDelegationTokenBinding#getUserAgentField()}}
   * for the current binding.
   * @return a string for the S3 logs or "" for "nothing to add"
   */
  public String getUserAgentField() {
    return tokenBinding.getUserAgentField();
  }

  /**

View on GitHub (pinned to 2add963021)

Solutions

  1. Remove the token for that s3a URI from the credentials (new Credentials for the job, or cancel the token) and let the filesystem deploy unbonded
  2. Ensure the delegation-token binding that issued the token is on the classpath and configured on consumers
  3. Re-fetch a fresh token after aligning versions
Defensive patterns

Strategy: try-catch

Validate before calling

if (token.decodeIdentifier() == null) {
  credentials.removeToken(token.getService());
  LOG.warn("Token kind {} for {} cannot be decoded; removed", token.getKind(), token.getService());
}

Try / catch

try {
  tokens.bindToAnyDelegationToken();
} catch (DelegationTokenIOException e) {
  if (e.getMessage().contains("Failed to unmarshall token")) {
    credentials.removeToken(new Text(canonicalUri)); // unknown-kind token: purge and rebind
    tokens.bindToAnyDelegationToken();
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: A token of an unknown/unregistered kind (or with an empty payload) is present in the user's credentials for the s3a service, and decodeTokenIdentifier processes it during binding.

Common situations: Tokens from other S3A-compatible systems or old versions left in a credentials file; a token kind registered by a binding that is no longer on the classpath; partially written token stores.

Related errors


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