prestodb/presto · error · OrcCorruptionException
Failed to read or decrypt FileStatistics for node %s
Error message
Failed to read or decrypt FileStatistics for node %s
What it means
DwrfMetadataReader.decryptAndCombineFileStatistics reads and optionally decrypts per-node FileStatistics from the metadata. If reading or decrypting those protobuf statistics raises IOException, it is wrapped into OrcCorruptionException because the file statistics section is unreadable (corrupt bytes or decryption failure).
Source
Thrown at presto-orc/src/main/java/com/facebook/presto/orc/metadata/DwrfMetadataReader.java:254
orcDataSource.getId(),
// Memory is not accounted as the buffer is expected to be tiny and will be immediately discarded
new SharedBuffer(NOOP_ORC_LOCAL_MEMORY_CONTEXT),
new BasicSliceInput(encryptedFileStats),
decompressor,
Optional.of(decryptor),
NOOP_ORC_AGGREGATED_MEMORY_CONTEXT,
encryptedFileStats.length())) {
CodedInputStream input = CodedInputStream.newInstance(inputStream);
DwrfProto.FileStatistics nodeStats = DwrfProto.FileStatistics.parseFrom(input);
// FileStatistics contains ColumnStatistics for the node and all its child nodes (subtree)
for (int statsIdx = 0; statsIdx < nodeStats.getStatisticsCount(); statsIdx++) {
decryptedFileStats[nodeId + statsIdx] =
toColumnStatistics(hiveWriterVersion, nodeStats.getStatistics(statsIdx), false, null);
}
}
catch (IOException e) {
throw new OrcCorruptionException(e, orcDataSource.getId(), "Failed to read or decrypt FileStatistics for node %s", nodeId);
}
}
}
return ImmutableList.copyOf(decryptedFileStats);
}
private static DwrfEncryption toEncryption(DwrfProto.Encryption encryption)
{
KeyProvider keyProvider = toKeyProvider(encryption.getKeyProvider());
List<EncryptionGroup> encryptionGroups = toEncryptionGroups(encryption.getEncryptionGroupsList());
return new DwrfEncryption(keyProvider, encryptionGroups);
}
private static List<EncryptionGroup> toEncryptionGroups(List<DwrfProto.EncryptionGroup> encryptionGroups)
{
ImmutableList.Builder<EncryptionGroup> encryptionGroupBuilder = ImmutableList.builderWithExpectedSize(encryptionGroups.size());
for (DwrfProto.EncryptionGroup dwrfEncryptionGroup : encryptionGroups) {View on GitHub (pinned to 55bb57d202)
Solutions
- Verify the encryption keys/key material available to the reader match those used by the writer (update kek metadata / key provider config).
- Validate the file metadata section with DWRF tooling to distinguish corruption from decryption failure.
- Restore the file from a known-good copy if the metadata block is corrupt.
- Ensure the writer that produced the file completed successfully and the full metadata was flushed.
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure decryption keys are configured before reading checkState(encryptionKeyMaterialPresent(), "DWRF decryption keys unavailable for %s", dataSourceId);
Try / catch
try { footer = metadataReader.readFooter(...); }
catch (OrcCorruptionException e) {
if (e.getMessage().contains("FileStatistics")) { reloadKeysAndRetryOnce(); }
else throw e;
} Prevention
- Provision writer-matching encryption keys on reader nodes
- Rotate keys only after all dependent files are rewritten
- Verify post-write metadata readability in pipelines
When it happens
Trigger: readFooter calls decryptAndCombineFileStatistics on a DWRF file whose metadata section fails protobuf parse or decryption (wrong encryption keys/kek material), producing IOException.
Common situations: DWRF encryption configured with different/rotated keys on read side, corrupted metadata blocks, files copied across clusters without key material, or truncated metadata.
Related errors
- Encrypted data size %s exceeds limit of 2^23
- Stripe encryption keys are missing, but file is encrypted
- Number of stripe encryption keys did not match number of enc
- GENERIC_INTERNAL_ERROR
- HIVE_INVALID_ENCRYPTION_METADATA
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/93c8d4b5eef18ba9.
Report an issue: GitHub.