{"record":{"id":"e92b720adc9bf37e","repo":"prestodb/presto","slug":"column-encrypted-with-footer-key-in-file-with-plai","errorCode":null,"errorMessage":"Column encrypted with footer key in file with plaintext footer","messagePattern":"Column encrypted with footer key in file with plaintext footer","errorType":"exception","errorClass":"ParquetCryptoRuntimeException","httpStatus":null,"severity":"error","filePath":"presto-parquet/src/main/java/com/facebook/presto/parquet/cache/MetadataReader.java","lineNumber":224,"sourceCode":"                                    || (filePath != null && filePath.equals(columnChunk.getFile_path())),\n                            \"all column chunks of the same row group must be in the same file\");\n\n                    ColumnMetaData metaData = columnChunk.meta_data;\n                    ColumnCryptoMetaData cryptoMetaData = columnChunk.getCrypto_metadata();\n                    ColumnPath columnPath = null;\n                    boolean encryptedMetadata = false;\n\n                    if (null == cryptoMetaData) { // Plaintext column\n                        columnPath = getPath(metaData);\n                        if (fileDecryptor.isPresent() && !fileDecryptor.get().plaintextFile()) {\n                            // mark this column as plaintext in encrypted file decryptor\n                            fileDecryptor.get().setColumnCryptoMetadata(columnPath, false, false, (byte[]) null, columnOrdinal);\n                        }\n                    }\n                    else {  // Encrypted column\n                        if (cryptoMetaData.isSetENCRYPTION_WITH_FOOTER_KEY()) { // Column encrypted with footer key\n                            if (!encryptedFooter) {\n                                throw new ParquetCryptoRuntimeException(\"Column encrypted with footer key in file with plaintext footer\");\n                            }\n                            if (null == metaData) {\n                                throw new ParquetCryptoRuntimeException(\"ColumnMetaData not set in Encryption with Footer key\");\n                            }\n                            if (!fileDecryptor.isPresent()) {\n                                throw new ParquetCryptoRuntimeException(\"Column encrypted with footer key: No keys available\");\n                            }\n                            columnPath = getPath(metaData);\n                            fileDecryptor.get().setColumnCryptoMetadata(columnPath, true, true, (byte[]) null, columnOrdinal);\n                        }\n                        else { // Column encrypted with column key\n                            try {\n                                // TODO: We decrypted data before filter projection. This could send unnecessary traffic to KMS. This so far not seen a problem in production.\n                                // In parquet-mr, it uses lazy decryption but that required to change ColumnChunkMetadata. We will improve it later.\n                                EncryptionWithColumnKey columnKeyStruct = cryptoMetaData.getENCRYPTION_WITH_COLUMN_KEY();\n                                List<String> pathList = columnKeyStruct.getPath_in_schema();\n                                byte[] columnKeyMetadata = columnKeyStruct.getKey_metadata();\n                                columnPath = ColumnPath.get(pathList.toArray(new String[pathList.size()]));","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-parquet/src/main/java/com/facebook/presto/parquet/cache/MetadataReader.java#L206-L242","documentation":"A column's crypto metadata declares ENCRYPTION_WITH_FOOTER_KEY (the column is encrypted with the same key as the footer), but the footer itself was read as plaintext. The library throws because in a plaintext-footer file every encrypted column must use its own column key; footer-key encryption is only valid when the footer is encrypted (otherwise there is no footer key to recover).","triggerScenarios":"convertToParquetMetadata processes a column chunk whose cryptoMetaData has ENCRYPTION_WITH_FOOTER_KEY set while encryptedFooter is false (plaintext footer read mode).","commonSituations":"Corrupt or hand-edited Parquet files mixing plaintext footers with footer-key-encrypted columns; files written by nonconformant writers that misuse the encryption metadata fields; version mismatch between writer and reader encryption spec interpretation.","solutions":["Regenerate the file with a compliant encryption-aware writer (parquet-mr with column encryption configured correctly)","If columns are truly footer-key encrypted, re-write the file with an encrypted footer","Check the writing library version — some older writers emitted inconsistent plaintext-footer/footer-key combos","If the file is actually unencrypted, read it without a decryptor so this branch isn't taken"],"exampleFix":"// before: writer config mismatch\nconf.set(\"parquet.encryption.column.keys\", \"keyA: col.ssn\"); // footer left plaintext\n// after\nconf.set(\"parquet.encryption.footer.key\", \"footerKey\"); // footer-key columns require encrypted footer","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    readParquetMetadata(dataSource);\n} catch (ParquetCryptoRuntimeException e) {\n    if (e.getMessage().contains(\"encrypted with footer key in file with plaintext footer\")) {\n        // treat file as corrupt/nonconformant: surface a table-read error\n        throw new DataCorruptionException(file, e);\n    } else throw e;\n}","preventionTips":["Write encrypted Parquet only with spec-compliant writers (parquet-mr >= encryption support)","Always configure a footer key when using footer-key-encrypted columns","Round-trip validate encrypted files after writing"],"tags":["parquet","encryption","corrupt-file"],"backgroundTag":"footer-key-column-in-plaintext-footer","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}