prestodb/presto · error · OrcCorruptionException
Unexpected row group %s in stripe at offset %s
Error message
Unexpected row group %s in stripe at offset %s
What it means
Write validation compares per-row-group statistics recorded at write time to those read back. The recorded stripe has fewer row groups than the row group index requested, so the reader cannot validate that row group and treats the file as corrupt.
Source
Thrown at presto-orc/src/main/java/com/facebook/presto/orc/OrcWriteValidation.java:447
stack.addAll(orcType.getFieldTypeIndexes());
}
}
return valueNodes.build();
}
public void validateRowGroupStatistics(
OrcDataSourceId orcDataSourceId,
long stripeOffset,
int rowGroupIndex,
List<ColumnStatistics> actual)
throws OrcCorruptionException
{
List<RowGroupStatistics> rowGroups = rowGroupStatistics.get(stripeOffset);
if (rowGroups == null) {
throw new OrcCorruptionException(orcDataSourceId, "Unexpected stripe at offset %s", stripeOffset);
}
if (rowGroups.size() <= rowGroupIndex) {
throw new OrcCorruptionException(orcDataSourceId, "Unexpected row group %s in stripe at offset %s", rowGroupIndex, stripeOffset);
}
// exclude stats for flat map keys because they are not present in the row group stats
ImmutableList.Builder<ColumnStatistics> actualAdjusted = ImmutableList.builder();
ImmutableMap.Builder<Integer, ColumnStatistics> actualAdjustedByNode = ImmutableMap.builder();
for (int i = 1; i < actual.size(); i++) {
if (!flattenedKeyToMapNodes.containsKey(i)) {
actualAdjusted.add(actual.get(i));
actualAdjustedByNode.put(i, actual.get(i));
}
}
RowGroupStatistics expectedRowGroup = rowGroups.get(rowGroupIndex);
RowGroupStatistics actualRowGroup = new RowGroupStatistics(BOTH, actualAdjustedByNode.build());
if (expectedRowGroup.getValidationMode() != HASHED) {
Map<Integer, ColumnStatistics> expectedByColumnIndex = expectedRowGroup.getColumnStatistics();
View on GitHub (pinned to 55bb57d202)
Solutions
- Restore/re-download the file — it was likely modified or corrupted after writing
- Re-write the file with the Presto ORC writer
- Align row group size settings between writer and reader clusters if validation metadata is version-skewed
- Set orc.write-validation=false if reading files from other engines where this metadata is absent
Defensive patterns
Strategy: validation
Validate before calling
// Ensure row group size matches the writer's setting before enabling validation
// e.g. writer used 10000 rows per row group
assert session.getSystemProperty("orc_row_group_size").equals("1MB"); // keep aligned with writer Try / catch
try {
orcBatchReader.nextPage();
} catch (OrcCorruptionException e) {
if (e.getMessage().contains("Unexpected row group")) {
// file metadata altered; re-read with validation off or restore backup
}
} Prevention
- Avoid modifying ORC files after writing
- Use identical ORC configurations on writer and reader clusters
- Verify file integrity after any copy/compaction step
- Disable validation for third-party-written files
When it happens
Trigger: validateRowGroupStatistics called with rowGroupIndex >= number of recorded row groups for the stripe at stripeOffset — typically a stripe whose ROW_INDEX entry count changed after write (file modified, corrupted footer/metadata).
Common situations: Files post-processed by compaction tools; partial/corrupted writes; reader and writer disagreeing on row-group sizing (different orc-row-group-size defaults).
Related errors
- Unexpected multiple column statistics for node %s in row gro
- Write validation failed: %s in %s statistics
- HIVE_CURSOR_ERROR
- File has no columns
- Stripe encryption keys are missing, but file is encrypted
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/d025f85b5ae99aef.
Report an issue: GitHub.