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

  1. Inspect the nested S3Exception status code: 404 means the key is gone, 403 means permissions, otherwise suspect network/endpoint.
  2. Verify with: aws s3api head-object --bucket <bucket> --key <key> using the same credentials Flink uses.
  3. Fix IAM/bucket policy to allow s3:GetObject on the bucket for HEAD requests.
  4. Check s3.endpoint and s3.path.style.access settings match the bucket's actual region/layout.
  5. 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

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


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/7dd263ac2ad2d67c. Report an issue: GitHub.