{"record":{"id":"1b7460d5e13333fd","repo":"apache/hadoop","slug":"we-expect-to-read-but-we-actually-read","errorCode":null,"errorMessage":"We expect to read {}, but we actually read: {}","messagePattern":"We expect to read (.+?), but we actually read: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"critical","filePath":"hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-nativetask/src/main/java/org/apache/hadoop/mapred/nativetask/handlers/BufferPushee.java","lineNumber":132,"sourceCode":"  }\n\n  @SuppressWarnings(\"unchecked\")\n  private boolean write(InputBuffer input) throws IOException {\n    if (closed) {\n      return false;\n    }\n    int totalRead = 0;\n    final int remain = input.remaining();\n    this.nativeReader.reset(input);\n    while (remain > totalRead) {\n      final int read = deserializer.deserializeKV(nativeReader, tmpOutputKey, tmpOutputValue);\n      if (read != 0) {\n        totalRead += read;\n        writer.write((OK) (tmpOutputKey.v), (OV) (tmpOutputValue.v));\n      }\n    }\n    if (remain != totalRead) {\n      throw new IOException(\"We expect to read \" + remain +\n                            \", but we actually read: \" + totalRead);\n    }\n    return true;\n  }\n\n  @Override\n  public void close() throws IOException {\n    if (closed) {\n      return;\n    }\n    if (null != writer) {\n      writer.close(null);\n    }\n    if (null != nativeReader) {\n      nativeReader.close();\n    }\n    closed = true;\n  }","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-nativetask/src/main/java/org/apache/hadoop/mapred/nativetask/handlers/BufferPushee.java#L114-L150","documentation":"After deserializing a whole input buffer, BufferPushee accumulates the byte count each deserializeKV() reports and requires the total to equal the buffer's remaining() captured up front. A mismatch throws IOException('We expect to read R, but we actually read: T') - the deserializer's self-reported lengths do not add up to the bytes actually present, i.e. the data or the length framing is inconsistent. This is the strongest corruption signal of the buffer-handoff checks.","triggerScenarios":"deserializeKV reports per-record read sizes that under- or over-count versus the buffer contents: mismatched serializer/deserializer implementations, records whose declared key/value lengths disagree with the payload, or buffers corrupted between producer and consumer.","commonSituations":"Custom INativeSerializer getBytesWritten/value length bugs; cross-version clusters where framing changed; disk or network corruption of intermediate data; native library built with different struct packing/alignment than the Java side assumes.","solutions":["Unit-test the custom serializer/deserializer pair against round-trip framing: sum of reported reads must equal serialized size for random KV sequences","Align Hadoop jar and libnativetask.so versions across client and cluster","Run the job with the native collector disabled to confirm the data path itself is sound, isolating the native framing layer"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  boolean done = pushee.collectData();\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"We expect to read\")) {\n    // deserializer-reported byte counts disagree with buffer contents -> data/framing corruption\n    // capture the buffer snapshot for diagnosis; rerun the task once on a different node\n    throw new IOException(\"nativetask length mismatch; suspected corruption or serializer bug\", e);\n  }\n  throw e;\n}","preventionTips":["Property-test custom deserializers: sum of deserializeKV return values must equal buffer remaining()","Align serializer/deserializer implementations and versions on both ends of the buffer handoff","Escalate persistent mismatches as data-integrity incidents - this error means bytes read != bytes present"],"tags":["nativetask","data-corruption","serialization","buffer-management"],"backgroundTag":"deserialized-length-mismatch","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}