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

  1. Discard the token and fetch a fresh one from a filesystem configured for delegation tokens
  2. Align hadoop-aws versions between the token issuer and consumers so serialization matches
  3. 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

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


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