apache/hadoop · error · IOException
Negative length
Error message
Negative length
What it means
While deserializing a PartHandle payload (S3AMultipartUploader.parsePartHandlePayload), the length field read via DataInputStream.readLong() must be >= 0; a negative value throws IOException("Negative length"). The part handle bytes are corrupt or were not written by the compatible S3A serializer, so the fixed field layout (header, path, uploadId, partNumber, len, etag) decoded to nonsense.
Source
Thrown at hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/impl/S3AMultipartUploader.java:334
try (DataInputStream input =
new DataInputStream(new ByteArrayInputStream(data))) {
final String header = input.readUTF();
if (!HEADER.equals(header)) {
throw new IOException("Wrong header string: \"" + header + "\"");
}
final String path = input.readUTF();
final String uploadId = input.readUTF();
final int partNumber = input.readInt();
final long len = input.readLong();
final String etag = input.readUTF();
String checksumAlgorithm = null;
String checksum = null;
if (input.available() > 0) {
checksumAlgorithm = input.readUTF();
checksum = input.readUTF();
}
if (len < 0) {
throw new IOException("Negative length");
}
return new PartHandlePayload(path, uploadId, partNumber, len, etag, checksumAlgorithm,
checksum);
}
}
static Map.Entry<String, String> extractChecksum(final UploadPartResponse uploadPartResponse) {
if (uploadPartResponse.checksumCRC32() != null) {
return new AbstractMap.SimpleEntry<>("CRC32", uploadPartResponse.checksumCRC32());
}
if (uploadPartResponse.checksumCRC32C() != null) {
return new AbstractMap.SimpleEntry<>("CRC32C", uploadPartResponse.checksumCRC32C());
}
if (uploadPartResponse.checksumSHA1() != null) {
return new AbstractMap.SimpleEntry<>("SHA1", uploadPartResponse.checksumSHA1());
}
if (uploadPartResponse.checksumSHA256() != null) {
return new AbstractMap.SimpleEntry<>("SHA256", uploadPartResponse.checksumSHA256());View on GitHub (pinned to 2add963021)
Solutions
- Discard the bad part handle, abort the multipart upload, and re-upload that part from the source data.
- Ensure every part handle given to complete() came from the upload() call of the same S3A uploader/version - do not synthesize or mutate them.
- If you store handles externally, verify length integrity (store length alongside, or checksum the blob) before reuse.
- Pin all cluster nodes to a single hadoop-aws/hadoop-common version so the serialization format matches.
Example fix
// before
byte[] partHandle = loadFromQueue(); // may be stale/corrupt
uploader.complete(path, uploadHandle, List.of(new PartHandle(partHandle)));
// after: recover by re-uploading the part
try {
uploader.complete(path, uploadHandle, partHandles);
} catch (IOException e) { // covers "Negative length" / "Wrong header string"
uploader.abort(uploadHandle);
uploadPartAgainAndComplete();
} Defensive patterns
Strategy: try-catch
Try / catch
try {
uploader.complete(path, uploadHandle, parts);
} catch (IOException e) {
if (e.getMessage().contains("Negative length")
|| e.getMessage().contains("Wrong header string")) {
uploader.abort(uploadHandle);
reuploadAllPartsAndComplete(); // corrupt handle: rebuild it
} else { throw e; }
} Prevention
- Keep part handles in memory within the upload session; do not store them in external systems.
- Run all participants on one hadoop-aws version to keep the payload format identical.
- Add integrity metadata (length + checksum) if you must externalize handles.
When it happens
Trigger: Corrupted or truncated PartHandle byte arrays passed to complete(); handles from an incompatible Hadoop version with a different field layout; bit flips from faulty storage of the handle blob; appends to the handle array shifting field offsets.
Common situations: Persisting part handles in an external store/queue that truncates or alters bytes; upgrading Hadoop between versions that changed the payload format (e.g. addition of checksum fields); unit tests fabricating handle bytes.
Related errors
- Wrong header string: \"" + header + "\"
- Multipart part path mismatch: " + path
- Multipart part ID mismatch: " + uploadId
- Path must be absolute: " + path
- Bucket doesn't match for source '%s' and destination '%s'!
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/acbc734f032f27ae.
Report an issue: GitHub.