prestodb/presto · error · PrestoException
HIVE_PARTITION_SCHEMA_MISMATCH
HIVE_PARTITION_SCHEMA_MISMATCH
Error message
The column %s of table %s is declared as type %s, but the Parquet file (%s) declares the column as type %s
What it means
Presto throws HIVE_PARTITION_SCHEMA_MISMATCH from getParquetType when a column's Hive-declared type differs from the type found in the Parquet file's schema. The Hive metastore schema and the physical file are compared per column; any divergence (including nested group types, whose Parquet name is built via writeToStringBuilder) causes the read to be aborted rather than silently returning wrong data.
Source
Thrown at presto-hive/src/main/java/com/facebook/presto/hive/parquet/ParquetPageSourceFactory.java:391
type = messageType.getType(column.getHiveColumnIndex());
}
if (type == null) {
return Optional.empty();
}
if (!checkSchemaMatch(type, prestoType)) {
String parquetTypeName;
if (type.isPrimitive()) {
parquetTypeName = type.asPrimitiveType().getPrimitiveTypeName().toString();
}
else {
GroupType group = type.asGroupType();
StringBuilder builder = new StringBuilder();
group.writeToStringBuilder(builder, "");
parquetTypeName = builder.toString();
}
throw new PrestoException(HIVE_PARTITION_SCHEMA_MISMATCH, format("The column %s of table %s is declared as type %s, but the Parquet file (%s) declares the column as type %s",
column.getName(),
tableName.toString(),
column.getHiveType(),
path.toString(),
parquetTypeName));
}
return Optional.of(type);
}
public static boolean checkSchemaMatch(org.apache.parquet.schema.Type parquetType, Type type)
{
String prestoType = type.getTypeSignature().getBase();
if (parquetType instanceof GroupType) {
GroupType groupType = parquetType.asGroupType();
switch (prestoType) {
case ROW:
RowType rowType = (RowType) type;
Map<String, Type> prestoFieldMap = rowType.getFields().stream().collect(View on GitHub (pinned to 55bb57d202)
Solutions
- Align the metastore schema with the actual Parquet file types (ALTER TABLE ... CHANGE COLUMN back, or recreate the table with the file's types)
- Rewrite the mismatched files so their Parquet types match the declared Hive schema (INSERT OVERWRITE / CTAS)
- If a specific partition's files are wrong, rewrite only that partition's files or drop/replace the partition
- Check which writer produced the files and configure it to emit Parquet types matching the Hive schema (e.g. disable INT96 timestamps, use spark.sql.parquet.int96TimestampConversion appropriately)
Example fix
// before: files written as INT32 while table declares bigint CREATE TABLE t (id int) STORED AS PARQUET; -- files have int32 but metastore says bigint after ALTER -- after: rewrite files to match schema INSERT OVERWRITE TABLE t SELECT CAST(id AS INT) AS id FROM t_raw; -- or fix metastore to match files
Defensive patterns
Strategy: validation
Validate before calling
// Validate Parquet file schema against the metastore table before querying/ingesting
ParquetFileReader reader = ParquetFileReader.open(conf, new Path(filePath));
MessageType fileSchema = reader.getFileMetaData().getSchema();
for (ColumnHandle handle : expectedColumns) {
HiveColumnHandle col = (HiveColumnHandle) handle;
Type fileCol = fileSchema.getType(col.getName());
if (fileCol == null || !parquetTypeMatches(col.getHiveType(), fileCol)) {
throw new IllegalStateException("Schema mismatch for column " + col.getName() +
": metastore=" + col.getHiveType() + " file=" + fileCol);
}
} Type guard
function parquetTypeMatches(hiveType, parquetType) {
if (parquetType == null) return false;
const normalized = normalizeHiveType(hiveType); // e.g. 'bigint'->'int64'
return normalized === parquetType.toString();
} Try / catch
try {
readParquetSplit(split);
} catch (PrestoException e) {
if (HIVE_PARTITION_SCHEMA_MISMATCH.equals(e.getErrorCode())) {
LOG.error("Falling back: file %s does not match table schema", split.getPath());
// route to repair/requeue rather than failing the whole query
} else { throw e; }
} Prevention
- After ALTER TABLE CHANGE COLUMN, always rewrite affected files (INSERT OVERWRITE) so physical types match
- Standardize one writer (version + settings) for Parquet files registered in the same table
- Run a periodic schema-consistency check (metastore vs parquet footer) over partitions
- Avoid INT96 timestamps; declare timestamps in the table exactly as written (TIMESTAMP_MICROS etc.)
When it happens
Trigger: Reading a Parquet-backed Hive table where column.getName()'s Hive type (column.getHiveType()) does not match the Parquet schema's type for that column; typically hit inside createParquetPageSource when a split is read after the table schema was altered without rewriting files, or when files written by a different writer (different Parquet types, e.g. INT96 vs TIMESTAMP, INT32 vs INT64) were registered under the table.
Common situations: ALTER TABLE CHANGE COLUMN / Hive schema evolution on data not rewritten; writing files with Spark/Impala using incompatible logical types then querying via Presto; partition-level schema drift where one partition's files differ from the metastore schema; timestamp columns stored as INT96 vs annotated TIMESTAMP_MICROS.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/4765a759146c1504.
Report an issue: GitHub.