apache/flink · error · IOException
Failed to get metadata for key: {}
Error message
Failed to get metadata for key: {} What it means
Thrown by NativeS3ObjectOperations.getObjectMetadata when the underlying s3Client.headObject call raises an S3Exception. A HEAD request is used to cheaply fetch object size, ETag, and last-modied time; any rejection (missing key, no permission, connectivity) is wrapped into an IOException naming the key.
Source
Thrown at flink-filesystems/flink-s3-fs-native/src/main/java/org/apache/flink/fs/s3native/writer/NativeS3ObjectOperations.java:449
return;
}
try {
stream.abort();
} catch (RuntimeException e) {
LOG.debug("Error aborting S3 response stream", e);
}
IOUtils.closeQuietly(stream);
}
public ObjectMetadata getObjectMetadata(String key) throws IOException {
try {
HeadObjectRequest request =
HeadObjectRequest.builder().bucket(bucketName).key(key).build();
HeadObjectResponse response = s3Client.headObject(request);
return new ObjectMetadata(
response.contentLength(), response.eTag(), response.lastModified());
} catch (S3Exception e) {
throw new IOException("Failed to get metadata for key: " + key, e);
}
}
public String getBucketName() {
return bucketName;
}
/**
* Extracts the S3 object key from a Flink Path.
*
* <p>Expected URI format: {@code s3://bucket-name/path/to/object}
*
* <p><b>Limitations:</b> This method only supports the standard S3 URI format. Other URI
* formats are NOT supported:
*
* <ul>
* <li>{@code https://bucket.s3.amazonaws.com/path/to/object} (virtual-hosted style)
* <li>{@code https://s3.amazonaws.com/bucket/path/to/object} (path style)View on GitHub (pinned to 2f3c205e92)
Solutions
- Inspect the nested S3Exception status code: 404 means the key is gone, 403 means permissions, otherwise suspect network/endpoint.
- Verify with: aws s3api head-object --bucket <bucket> --key <key> using the same credentials Flink uses.
- Fix IAM/bucket policy to allow s3:GetObject on the bucket for HEAD requests.
- Check s3.endpoint and s3.path.style.access settings match the bucket's actual region/layout.
- Retry on 5xx/timeout — HEAD is idempotent.
Defensive patterns
Strategy: retry
Validate before calling
try {
s3Client.headObject(HeadObjectRequest.builder().bucket(bucket).key(key).build());
} catch (NoSuchKeyException e) {
// key absent — decide before calling getObjectMetadata
} Try / catch
try {
ObjectMetadata md = s3AccessHelper.getObjectMetadata(key);
} catch (IOException e) {
if (e.getCause() instanceof S3Exception
&& ((S3Exception) e.getCause()).statusCode() == 404) {
// treat as absent
return Optional.empty();
}
throw e;
} Prevention
- Grant s3:GetObject on the checkpoint bucket in IAM.
- Use HEAD-based existence checks instead of GET where possible.
- Align s3.endpoint with the bucket region.
When it happens
Trigger: Calling getObjectMetadata(key) — used to check existence/size of parts or target objects during commit/recovery — when the key does not exist (404), the caller lacks s3:GetObject permission, the bucket/endpoint is misconfigured, or the network fails.
Common situations: Committing a multipart upload whose already-uploaded part objects were removed; IAM policy missing head-object permission; s3.endpoint configured for the wrong region; clock-skew induced 403s; concurrent cleanup deleting the object between listing and HEAD.
Related errors
- An I/O error occurred while creating temporary file to extra
- Failed to create parent(s) for given base dir: %s
- Failed to list contents of {directory}
- Failed to get object for key: {}
- Incomplete-tail file does not exist: {}
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/7dd263ac2ad2d67c.
Report an issue: GitHub.