{"record":{"id":"acbc734f032f27ae","repo":"apache/hadoop","slug":"negative-length-acbc73","errorCode":null,"errorMessage":"Negative length","messagePattern":"Negative length","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/impl/S3AMultipartUploader.java","lineNumber":334,"sourceCode":"    try (DataInputStream input =\n             new DataInputStream(new ByteArrayInputStream(data))) {\n      final String header = input.readUTF();\n      if (!HEADER.equals(header)) {\n        throw new IOException(\"Wrong header string: \\\"\" + header + \"\\\"\");\n      }\n      final String path = input.readUTF();\n      final String uploadId = input.readUTF();\n      final int partNumber = input.readInt();\n      final long len = input.readLong();\n      final String etag = input.readUTF();\n      String checksumAlgorithm = null;\n      String checksum = null;\n      if (input.available() > 0) {\n        checksumAlgorithm = input.readUTF();\n        checksum = input.readUTF();\n      }\n      if (len < 0) {\n        throw new IOException(\"Negative length\");\n      }\n      return new PartHandlePayload(path, uploadId, partNumber, len, etag, checksumAlgorithm,\n          checksum);\n    }\n  }\n\n  static Map.Entry<String, String> extractChecksum(final UploadPartResponse uploadPartResponse) {\n    if (uploadPartResponse.checksumCRC32() != null) {\n      return new AbstractMap.SimpleEntry<>(\"CRC32\", uploadPartResponse.checksumCRC32());\n    }\n    if (uploadPartResponse.checksumCRC32C() != null) {\n      return new AbstractMap.SimpleEntry<>(\"CRC32C\", uploadPartResponse.checksumCRC32C());\n    }\n    if (uploadPartResponse.checksumSHA1() != null) {\n      return new AbstractMap.SimpleEntry<>(\"SHA1\", uploadPartResponse.checksumSHA1());\n    }\n    if (uploadPartResponse.checksumSHA256() != null) {\n      return new AbstractMap.SimpleEntry<>(\"SHA256\", uploadPartResponse.checksumSHA256());","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/impl/S3AMultipartUploader.java#L316-L352","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nbyte[] partHandle = loadFromQueue(); // may be stale/corrupt\nuploader.complete(path, uploadHandle, List.of(new PartHandle(partHandle)));\n\n// after: recover by re-uploading the part\ntry {\n  uploader.complete(path, uploadHandle, partHandles);\n} catch (IOException e) { // covers \"Negative length\" / \"Wrong header string\"\n  uploader.abort(uploadHandle);\n  uploadPartAgainAndComplete();\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  uploader.complete(path, uploadHandle, parts);\n} catch (IOException e) {\n  if (e.getMessage().contains(\"Negative length\")\n      || e.getMessage().contains(\"Wrong header string\")) {\n    uploader.abort(uploadHandle);\n    reuploadAllPartsAndComplete(); // corrupt handle: rebuild it\n  } else { throw e; }\n}","preventionTips":["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."],"tags":["hadoop-aws","multipart-uploader","part-handle","corrupt-data","validation"],"backgroundTag":"corrupt-serialized-data","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}