prestodb/presto · error · ParquetCryptoRuntimeException

. Failed to decrypt column metadata

Error message

. Failed to decrypt column metadata

What it means

decryptMetadata wraps failures of Util.readColumnMetaData — the encrypted ColumnMetaData blob for a column could not be decrypted/authenticated (GCM tag mismatch, wrong key, wrong AAD) or the stream could not be parsed as thrift. The message is prefixed with the failing column path and the IOException is the cause.

Source

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

        }

        ParquetMetadata parquetMetadata = new ParquetMetadata(new org.apache.parquet.hadoop.metadata.FileMetaData(messageType, keyValueMetaData, fileMetaData.getCreated_by()), blocks);
        return new ParquetFileMetadata(parquetMetadata, toIntExact(metadataLength), modificationTime);
    }

    private static ColumnMetaData decryptMetadata(RowGroup rowGroup, byte[] columnKeyMetadata, ColumnChunk columnChunk, InternalFileDecryptor fileDecryptor, int columnOrdinal, ColumnPath columnPath)
    {
        byte[] encryptedMetadataBuffer = columnChunk.getEncrypted_column_metadata();

        // Decrypt the ColumnMetaData
        InternalColumnDecryptionSetup columnDecryptionSetup = fileDecryptor.setColumnCryptoMetadata(columnPath, true, false, columnKeyMetadata, columnOrdinal);
        ByteArrayInputStream tempInputStream = new ByteArrayInputStream(encryptedMetadataBuffer);
        byte[] columnMetaDataAAD = AesCipher.createModuleAAD(fileDecryptor.getFileAAD(), ModuleType.ColumnMetaData, rowGroup.ordinal, columnOrdinal, -1);
        try {
            return Util.readColumnMetaData(tempInputStream, columnDecryptionSetup.getMetaDataDecryptor(), columnMetaDataAAD);
        }
        catch (IOException e) {
            throw new ParquetCryptoRuntimeException(columnPath + ". Failed to decrypt column metadata", e);
        }
    }

    public static ColumnChunkMetaData buildColumnChunkMetaData(ColumnMetaData metaData, ColumnPath columnPath, PrimitiveType type)
    {
        return ColumnChunkMetaData.get(
                columnPath,
                type,
                CompressionCodecName.fromParquet(metaData.codec),
                PARQUET_METADATA_CONVERTER.convertEncodingStats(metaData.encoding_stats),
                readEncodings(metaData.encodings),
                readStats(metaData.statistics, type.getPrimitiveTypeName()),
                metaData.data_page_offset,
                metaData.dictionary_page_offset,
                metaData.num_values,
                metaData.total_compressed_size,
                metaData.total_uncompressed_size);
    }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Verify the correct footer/column key is configured for this table/file
  2. Check that encryption AAD prefix storage settings match the writer's (set encryption.algorithm / AAD prefix handling accordingly)
  3. Confirm the file was not truncated or corrupted in transit (checksum it)
  4. Upgrade the reader library if the file was written with a newer Parquet encryption spec revision

Example fix

// before: extra AAD ignored
conf.set("parquet.encryption.aad.prefix", null);
// after: supply the same AAD prefix used at write time
conf.set("parquet.encryption.aad.prefix", storedAadPrefix);
Defensive patterns

Strategy: try-catch

Validate before calling

// verify the key decrypts a known test blob from the same writer before reading
byte[] probe = fileCryptoMetaData.getNonce();
assertDecrypts(probe, configuredKey) : "configured key does not match file encryption key";

Try / catch

try {
    readParquetMetadata(dataSource);
} catch (ParquetCryptoRuntimeException e) {
    if (e.getMessage().endsWith("Failed to decrypt column metadata")) {
        // wrong key or AAD; alert with column path from message prefix
        alertKeyMismatch(e.getMessage(), e.getCause());
    } else throw e;
}

Prevention

When it happens

Trigger: During convertToParquetMetadata, decryptMetadata is invoked for an encrypted column and readColumnMetaData throws IOException — typically because the footer key or column key derived by the decryptor doesn't match the one used at write time, or the fileAAD/rowGroup ordinal/columnOrdinal AAD construction differs (e.g. files copied without AAD storage, or supply-AAD flag mismatch).

Common situations: Wrong key supplied for the dataset; file copied/moved losing encryption metadata; writer used extra AAD prefix but reader not configured with it; corrupted blocks; reading a file encrypted with a newer cipher suite than the reader supports.

Related errors


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