prestodb/presto · error · OrcCorruptionException
Write validation failed: unexpected string range in %s stati
Error message
Write validation failed: unexpected string range in %s statistics
What it means
For string columns, write validation compares StringStatistics (min/max/sum of lengths) recorded at write time to those read back. The reader is lenient about min/max when the expected value is null (string stats have length truncation limits, and merging row group stats can produce nulls), but sum of lengths must match and any present expected min/max must equal the actual. Mismatch indicates corrupted or altered string data/statistics.
Source
Thrown at presto-orc/src/main/java/com/facebook/presto/orc/OrcWriteValidation.java:576
StringStatistics expectedStringStatistics = expectedColumnStatistics.getStringStatistics();
if (expectedStringStatistics != null) {
expectedStringStatistics = new StringStatistics(
minStringTruncateToValidRange(expectedStringStatistics.getMin(), HiveWriterVersion.ORC_HIVE_8732),
maxStringTruncateToValidRange(expectedStringStatistics.getMax(), HiveWriterVersion.ORC_HIVE_8732),
expectedStringStatistics.isLowerBoundSet(),
expectedStringStatistics.isUpperBoundSet(),
expectedStringStatistics.getSum());
}
StringStatistics actualStringStatistics = actualColumnStatistics.getStringStatistics();
if (!Objects.equals(actualColumnStatistics.getStringStatistics(), expectedStringStatistics) && expectedStringStatistics != null) {
// expectedStringStatistics (or the min/max of it) could be null while the actual one might not because
// expectedStringStatistics is calculated by merging all row group stats in the stripe but the actual one is by scanning each row in the stripe on disk.
// Merging row group stats can produce nulls given we have string stats limit.
if (actualStringStatistics == null ||
actualStringStatistics.getSum() != expectedStringStatistics.getSum() ||
(expectedStringStatistics.getMax() != null && !Objects.equals(actualStringStatistics.getMax(), expectedStringStatistics.getMax())) ||
(expectedStringStatistics.getMin() != null && !Objects.equals(actualStringStatistics.getMin(), expectedStringStatistics.getMin()))) {
throw new OrcCorruptionException(orcDataSourceId, "Write validation failed: unexpected string range in %s statistics", name);
}
}
if (!Objects.equals(actualColumnStatistics.getDateStatistics(), expectedColumnStatistics.getDateStatistics())) {
throw new OrcCorruptionException(orcDataSourceId, "Write validation failed: unexpected date range in %s statistics", name);
}
if (!Objects.equals(actualColumnStatistics.getDecimalStatistics(), expectedColumnStatistics.getDecimalStatistics())) {
throw new OrcCorruptionException(orcDataSourceId, "Write validation failed: unexpected decimal range in %s statistics", name);
}
if (!Objects.equals(actualColumnStatistics.getBloomFilter(), expectedColumnStatistics.getBloomFilter())) {
throw new OrcCorruptionException(orcDataSourceId, "Write validation failed: unexpected bloom filter in %s statistics", name);
}
}
public static class WriteChecksum
{
private final long totalRowCount;
private final long stripeHash;
private final List<Long> columnHashes;View on GitHub (pinned to 55bb57d202)
Solutions
- Re-write the file with the Presto ORC writer so string statistics use the same truncation semantics
- If the file came from another engine, disable orc.write-validation for those reads
- Upgrade Presto to get consistent ORC_HIVE_8732 min/max range handling
- Restore the file if storage corruption is confirmed
Defensive patterns
Strategy: try-catch
Try / catch
try {
orcBatchReader.nextPage();
} catch (OrcCorruptionException e) {
if (e.getMessage().contains("unexpected string range")) {
// likely truncation-limit semantics mismatch; re-read with validation off or rewrite file
}
} Prevention
- Use one writer version (consistent ORC_HIVE_8732 string stats semantics) across clusters
- Disable write validation for files from other engines
- Re-write cross-engine files with Presto's ORC writer
- Upgrade Presto for consistent string min/max truncation handling
When it happens
Trigger: validateColumnStatisticsEquivalent finds actualStringStatistics null while expected is present, sum of string lengths differs, or a non-null expected min/max differs from the actual — at file, stripe, or row group level.
Common situations: Files written by engines with different string statistics truncation limits (HiveWriterVersion ORC_HIVE_8732 handling); corrupted string columns; cross-engine file exchange.
Related errors
- Unexpected multiple column statistics for node %s in row gro
- Write validation failed: unexpected number of columns in %s
- Write validation failed: %s in %s statistics
- Write validation failed: unexpected boolean counts in %s sta
- Write validation failed: unexpected integer range in %s stat
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/e87bd9cc0449e2e4.
Report an issue: GitHub.