{"record":{"id":"f53483ab88d6253c","repo":"apache/hadoop","slug":"decoding-s3a-token-cause","errorCode":null,"errorMessage":"Decoding S3A token {cause}","messagePattern":"Decoding S3A token (.+?)","errorType":"exception","errorClass":"DelegationTokenIOException","httpStatus":null,"severity":"error","filePath":"hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/auth/delegation/S3ADelegationTokens.java","lineNumber":585,"sourceCode":"   * @param token token to process\n   * @return the session token identifier\n   * @throws IOException failure to validate/read data encoded in identifier.\n   * @throws IllegalArgumentException if the token isn't an S3A session token\n   */\n  public AbstractS3ATokenIdentifier extractIdentifier(\n      final Token<? extends AbstractS3ATokenIdentifier> token)\n      throws IOException {\n\n    checkArgument(token != null, \"null token\");\n    AbstractS3ATokenIdentifier identifier;\n    // harden up decode beyond that Token does itself\n    try {\n      identifier = token.decodeIdentifier();\n    } catch (RuntimeException e) {\n      Throwable cause = e.getCause();\n      if (cause != null) {\n        // its a wrapping around class instantiation.\n        throw new DelegationTokenIOException(\"Decoding S3A token \" + cause,\n            cause);\n      } else {\n        throw e;\n      }\n    }\n    if (identifier == null) {\n      throw new DelegationTokenIOException(\"Failed to unmarshall token for \"\n          + getCanonicalUri());\n    }\n    identifier.validate();\n    return identifier;\n  }\n\n  /**\n   * Return a string for use in building up the User-Agent field, so\n   * get into the S3 access logs. Useful for diagnostics.\n   * Delegates to {{@link AbstractDelegationTokenBinding#getUserAgentField()}}\n   * for the current binding.","sourceCodeStart":567,"sourceCodeEnd":603,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/auth/delegation/S3ADelegationTokens.java#L567-L603","documentation":"While decoding a fetched delegation token, S3ADelegationTokens hardens Token.decodeIdentifier: if it throws a RuntimeException whose cause is non-null (typically a ClassNotFoundException or instantiation failure while creating the token identifier class from the token's kind), the cause is wrapped in DelegationTokenIOException 'Decoding S3A token <cause>'. The token payload is fine; the code to materialize its identifier is missing.","triggerScenarios":"token.decodeIdentifier() must instantiate the identifier class registered for the token kind; that class is absent from the decoding client's classpath. Common when the token was issued by a different Hadoop version or custom binding whose identifier class the consumer lacks.","commonSituations":"Cross-version token usage (token issued by newer hadoop-aws, decoded by older); custom binding's identifier jar missing on executors; distro mismatch between token issuer service and compute cluster.","solutions":["Put the missing identifier class's jar on the decoding client's classpath","Match hadoop-aws versions between token issuer and consumer","Remove the unusable token from credentials and re-authenticate directly until versions are aligned"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"try {\n  Class.forName(token.getKind().toString()); // identifier class must be loadable here\n} catch (ClassNotFoundException e) {\n  credentials.removeToken(token.getService());\n  LOG.warn(\"Removed s3a token whose identifier class {} is not on classpath\", token.getKind());\n}","typeGuard":null,"tryCatchPattern":"try {\n  AbstractS3ATokenIdentifier id = delegationTokens.decodeTokenIdentifier(token);\n} catch (DelegationTokenIOException e) {\n  if (e.getMessage().startsWith(\"Decoding S3A token\")) {\n    // missing identifier class: drop token and authenticate directly\n    credentials.removeToken(token.getService());\n    delegationTokens.bindToAnyDelegationToken();\n  } else {\n    throw e;\n  }\n}","preventionTips":["Match hadoop-aws versions between token issuer and consumers","Ship custom binding identifier jars to all executors","On decode failure, remove the token instead of retrying it"],"tags":["aws","s3a","delegation-token","classpath","class-not-found","deserialization"],"backgroundTag":"token-decode-failure","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}