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

  1. Discard the bad part handle, abort the multipart upload, and re-upload that part from the source data.
  2. Ensure every part handle given to complete() came from the upload() call of the same S3A uploader/version - do not synthesize or mutate them.
  3. If you store handles externally, verify length integrity (store length alongside, or checksum the blob) before reuse.
  4. 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

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


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