{"record":{"id":"4e0bda99ba12ea9c","repo":"apache/druid","slug":"unexpected-end-of-second-adapter","errorCode":null,"errorMessage":"Unexpected end of second adapter","messagePattern":"Unexpected end of second adapter","errorType":"validation","errorClass":"SegmentValidationException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/segment/IndexIO.java","lineNumber":182,"sourceCode":"            \"Dimension names differ. Expected [%s] found [%s]\",\n            dimNames1,\n            dimNames2\n        );\n      }\n      final Set<String> metNames1 = Sets.newHashSet(adapter1.getMetricNames());\n      final Set<String> metNames2 = Sets.newHashSet(adapter2.getMetricNames());\n      if (!metNames1.equals(metNames2)) {\n        throw new SegmentValidationException(\"Metric names differ. Expected [%s] found [%s]\", metNames1, metNames2);\n      }\n    }\n    try (\n        final RowIterator it1 = adapter1.getRows();\n        final RowIterator it2 = adapter2.getRows()\n    ) {\n      long row = 0L;\n      while (it1.moveToNext()) {\n        if (!it2.moveToNext()) {\n          throw new SegmentValidationException(\"Unexpected end of second adapter\");\n        }\n        final RowPointer rp1 = it1.getPointer();\n        final RowPointer rp2 = it2.getPointer();\n        ++row;\n        if (rp1.getRowNum() != rp2.getRowNum()) {\n          throw new SegmentValidationException(\"Row number mismatch: [%d] vs [%d]\", rp1.getRowNum(), rp2.getRowNum());\n        }\n        try {\n          validateRowValues(rp1, adapter1, rp2, adapter2);\n        }\n        catch (SegmentValidationException ex) {\n          throw new SegmentValidationException(ex, \"Validation failure on row %d: [%s] vs [%s]\", row, rp1, rp2);\n        }\n      }\n      if (it2.moveToNext()) {\n        throw new SegmentValidationException(\"Unexpected end of first adapter\");\n      }\n      if (row != adapter1.getNumRows()) {","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/IndexIO.java#L164-L200","documentation":"In validateTwoSegments, rows are walked in parallel via two RowIterators. If the first adapter still has rows but the second iterator is exhausted (it2.moveToNext() returns false), the second segment has fewer rows than reported/expected, and this SegmentValidationException is thrown.","triggerScenarios":"Row-by-row comparison loop where it1.moveToNext() succeeds but it2.moveToNext() fails — the second adapter terminated early despite matching declared row counts, or the earlier count check was bypassed.","commonSituations":"Corrupt or truncated segment files (version 9+ index.zxs truncated on disk); a bug in a custom IndexableAdapter/RowIterator; deep-storage corruption after a partial copy.","solutions":["Verify the second segment's files are intact (re-fetch from deep storage, check file sizes against segment metadata).","Re-run validateTwoSegments on a freshly downloaded copy to rule out transfer truncation.","If the segment is corrupt, re-ingest or restore it from backup before validating.","If a custom adapter is involved, debug its getRows()/iterator implementation for early termination."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  io.validateTwoSegments(adapter1, adapter2);\n} catch (SegmentValidationException e) {\n  if (e.getMessage().contains(\"Unexpected end of\")) {\n    log.error(\"Truncated/corrupt segment detected: %s\", e.getMessage());\n    // re-fetch segment from deep storage before retrying\n  }\n  throw e;\n}","preventionTips":["Verify segment file integrity after copying to/from deep storage.","Check file sizes (IndexIO.checkFileSize) before validating segments.","Avoid interrupting segment upload/download operations.","Restore from replicas if a segment copy fails midway."],"tags":["segment-validation","corruption","iteration"],"backgroundTag":"checksum-mismatch","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}