prestodb/presto · error · ParquetCryptoRuntimeException

Applying decryptor on plaintext file

Error message

Applying decryptor on plaintext file

What it means

MetadataReader.convertToParquetMetadata throws this when a fileDecryptor (key material/decryption configuration) is attached but the Parquet footer proves the file is completely unencrypted (no encryption_algorithm set). The library deliberately refuses to run a decryptor against plaintext because it means the reader was configured with keys for a file that is not encrypted — almost always a misconfiguration.

Source

Thrown at presto-parquet/src/main/java/com/facebook/presto/parquet/cache/MetadataReader.java:176

        }

        FileMetaData fileMetaData = readFileMetaData(input, footerDecryptor, additionalAuthenticationData);
        return convertToParquetMetadata(input, fileMetaData, metadataLength, modificationTime, fileDecryptor, encryptedFooterMode, id, readMaskedValue);
    }

    private static ParquetFileMetadata convertToParquetMetadata(BasicSliceInput input, FileMetaData fileMetaData, int metadataLength, long modificationTime, Optional<InternalFileDecryptor> fileDecryptor, boolean encryptedFooter, ParquetDataSourceId id, boolean readMaskedValue)
            throws IOException
    {
        List<SchemaElement> schema = fileMetaData.getSchema();
        validateParquet(!schema.isEmpty(), "Empty Parquet schema in file: %s", id);

        // Reader attached fileDecryptor. The file could be encrypted with plaintext footer or the whole file is plaintext.
        if (!encryptedFooter && fileDecryptor.isPresent()) {
            if (!fileMetaData.isSetEncryption_algorithm()) { // Plaintext file
                fileDecryptor.get().setPlaintextFile();
                // Detect that the file is not encrypted by mistake
                if (!fileDecryptor.get().plaintextFilesAllowed()) {
                    throw new ParquetCryptoRuntimeException("Applying decryptor on plaintext file");
                }
            }
            else {  // Encrypted file with plaintext footer
                // if no fileDecryptor, can still read plaintext columns
                fileDecryptor.get().setFileCryptoMetaData(fileMetaData.getEncryption_algorithm(), false,
                        fileMetaData.getFooter_signing_key_metadata());
                if (fileDecryptor.get().checkFooterIntegrity()) {
                    verifyFooterIntegrity(input, fileDecryptor.get(), metadataLength);
                }
            }
        }

        MessageType messageType = readParquetSchema(schema);
        List<BlockMetaData> blocks = new ArrayList<>();
        List<RowGroup> rowGroups = fileMetaData.getRow_groups();
        Set<ColumnPath> maskedColumns = new HashSet<>();
        if (rowGroups != null) {
            for (RowGroup rowGroup : rowGroups) {

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Remove the decryption configuration (keys/fileDecryptor) when reading unencrypted Parquet files, or scope it to only encrypted files
  2. Allow plaintext files in the decryption properties (enable plaintext files) if mixed encrypted/plaintext data is expected
  3. Verify the target file is actually encrypted (check Parquet magic/metadata) and fix the path
  4. Confirm the key retriever isn't applied globally via session/catalog defaults

Example fix

// before: decrypt props applied to all files
HiveSessionProperties.setParquetDecryptKeys(session, keys);
// after: only attach decryptor for encrypted files
if (isFileEncrypted(path)) {
    conf.set(ParquetInputFormat.DECRYPTION_KEY_RETRIEVER, retriever);
}
Defensive patterns

Strategy: validation

Validate before calling

// check footer encryption before configuring a decryptor
ParquetMetadata footer = readFooter(dataSource);
boolean encrypted = footer.getFileMetaData().isSetEncryption_algorithm();
if (!encrypted && decryptorConfigured) {
    throw new IllegalStateException("File is plaintext; remove decryptor or enable plaintext files");
}

Try / catch

try {
    readParquetMetadata(dataSource);
} catch (ParquetCryptoRuntimeException e) {
    if (e.getMessage().contains("Applying decryptor on plaintext file")) {
        // retry without decryption config
        readParquetMetadata(dataSourceWithoutDecryptor);
    } else throw e;
}

Prevention

When it happens

Trigger: Reading a Parquet file whose footer has encryptedFooter=false and no fileMetaData encryption_algorithm, while a non-empty fileDecryptor was supplied (e.g. via decryption configuration / DecryptionKeyRetriever) and plaintextFilesAllowed() returns false (plaintext files not permitted by config).

Common situations: Pointing an encryption-enabled reader at an unencrypted Parquet file; cluster/session-level encryption config applied to mixed encrypted/plaintext datasets; file swapped for a plaintext copy after keys were configured; disabling plaintext file acceptance while reading unencrypted legacy files.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/92d70c23b5dc24e1. Report an issue: GitHub.