apache/hadoop · error · DelegationTokenIOException
No URI in {this}
Error message
No URI in {this} What it means
Every S3A delegation token identifier must carry the canonical URI of the filesystem it was created for. After a token is decoded, AbstractS3ATokenIdentifier.validate() checks that uri is non-null and throws DelegationTokenIOException ('No URI in ...') otherwise. A null URI means the token payload was never populated correctly for this format, i.e. the token is corrupt or was serialized by an incompatible implementation.
Source
Thrown at hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/auth/delegation/AbstractS3ATokenIdentifier.java:242
*/
@Override
public void readFields(final DataInput in)
throws DelegationTokenIOException, IOException {
super.readFields(in);
uri = URI.create(Text.readString(in, MAX_TEXT_LENGTH));
origin = Text.readString(in, MAX_TEXT_LENGTH);
uuid = Text.readString(in, MAX_TEXT_LENGTH);
encryptionSecrets.readFields(in);
created = in.readLong();
}
/**
* Validate the token by looking at its fields.
* @throws IOException on failure.
*/
public void validate() throws IOException {
if (uri == null) {
throw new DelegationTokenIOException("No URI in " + this);
}
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder(
"S3ATokenIdentifier{");
sb.append(getKind());
sb.append("; uri=").append(uri);
sb.append("; timestamp=").append(created);
sb.append("; renewer=").append(getRenewer());
sb.append("; encryption=").append(encryptionSecrets.toString());
sb.append("; ").append(uuid);
sb.append("; ").append(origin);
sb.append('}');
return sb.toString();
}
View on GitHub (pinned to 2add963021)
Solutions
- Discard the token and fetch a fresh one from a filesystem configured for delegation tokens
- Align hadoop-aws versions between the token issuer and consumers so serialization matches
- If persisting credentials to a file, verify it is written/read as binary without corruption (no text-mode transfer, no partial writes)
Defensive patterns
Strategy: try-catch
Validate before calling
AbstractS3ATokenIdentifier id = (AbstractS3ATokenIdentifier) token.decodeIdentifier();
if (id == null || id.getUri() == null) {
credentials.removeToken(token.getService());
LOG.warn("Discarding malformed s3a token for {}", token.getService());
} Try / catch
try {
identifier.validate();
} catch (DelegationTokenIOException e) {
if (e.getMessage().startsWith("No URI in")) {
// corrupt/incompatible token: drop it and re-authenticate, do not retry the same token
credentials.removeToken(token.getService());
tokens.bindToAnyDelegationToken();
} else {
throw e;
}
} Prevention
- Align hadoop-aws versions across token issuers and consumers
- Transfer credentials files in binary mode; avoid partial writes
- After upgrades, expire and re-issue all delegation tokens
When it happens
Trigger: S3ADelegationTokens.decodeTokenIdentifier calls identifier.validate() after token.decodeIdentifier(); readFields populated fields but left uri null. This happens with truncated/foreign token bytes or an identifier class whose serialization does not set the URI.
Common situations: Tokens carried across Hadoop versions whose field order/format changed; hand-crafted or test-fabricated identifiers; token bytes mangled in transit or in a credentials store.
Related errors
- Incompatible EncryptionSecrets version: {versionId}
- Invalid format (Expected name, name:SignerClass, name:Signer
- Delegation token is wrong class; expected a token identifier
- 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/d040a2d77a8d4667.
Report an issue: GitHub.