prestodb/presto · error · PrestoException

HIVE_INVALID_PARTITION_VALUE

HIVE_INVALID_PARTITION_VALUE

Error message

partition key value cannot be null for field: %s

What it means

When parsing each partition name's key/value map for data predicates, every declared partition key must be present. If a partition key name is missing from the parsed map (null value), Presto throws HIVE_INVALID_PARTITION_VALUE, since a partition value cannot be null.

Source

Thrown at presto-hive/src/main/java/com/facebook/presto/hive/HiveMaterializedViewUtils.java:176

        List<HiveColumnHandle> partitionKeyColumnHandles = getPartitionKeyColumnHandles(table);
        Map<String, Type> partitionTypes = partitionKeyColumnHandles.stream()
                .collect(toImmutableMap(HiveColumnHandle::getName, column -> typeManager.getType(column.getTypeSignature())));

        List<PartitionNameWithVersion> partitionNames = metastore.getPartitionNames(metastoreContext, table.getDatabaseName(), table.getTableName())
                .orElseThrow(() -> new TableNotFoundException(new SchemaTableName(table.getDatabaseName(), table.getTableName())));

        ImmutableList.Builder<TupleDomain<String>> partitionNamesAndValues = ImmutableList.builder();
        for (PartitionNameWithVersion partitionName : partitionNames) {
            ImmutableMap.Builder<String, NullableValue> partitionNameAndValuesMap = ImmutableMap.builder();
            Map<String, String> partitions = toPartitionNamesAndValues(partitionName.getPartitionName());
            if (partitionColumns.size() != partitions.size()) {
                throw new PrestoException(HIVE_INVALID_METADATA, String.format(
                        "Expected %d partition key values, but got %d", partitionColumns.size(), partitions.size()));
            }
            partitionTypes.forEach((name, type) -> {
                String value = partitions.get(name);
                if (value == null) {
                    throw new PrestoException(HIVE_INVALID_PARTITION_VALUE, String.format("partition key value cannot be null for field: %s", name));
                }

                partitionNameAndValuesMap.put(name, parsePartitionValue(Optional.of(session), name, value, type, timeZone));
            });

            TupleDomain<String> tupleDomain = TupleDomain.fromFixedValues(partitionNameAndValuesMap.build());
            partitionNamesAndValues.add(tupleDomain);
        }

        return new MaterializedDataPredicates(partitionNamesAndValues.build(), partitionColumns.stream()
                .map(Column::getName)
                .collect(toImmutableList()));
    }

    // Every table on outer join side, must have a partition which is in EQ clause and present in Materialized View as well.
    // For a given base table, this function computes partition columns of Materialized View which are not directly mapped to base table,
    // and are directly mapped to some other base table which is not on outer join side.
    // For example:

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Drop and re-add the affected partitions with complete key=value specs
  2. Run MSCK REPAIR TABLE to resync partition metadata
  3. Inspect the partition directory names on storage and fix the missing key
  4. Fix the metastore partition record directly if the storage layout is correct

Example fix

-- before
ALTER TABLE t ADD PARTITION (ds='2024-01-01'); -- table has (ds, hr)
-- after
ALTER TABLE t ADD PARTITION (ds='2024-01-01', hr='00');
Defensive patterns

Strategy: validation

Validate before calling

partitionTypes.forEach((name, type) -> {
    if (parts.get(name) == null) {
        throw new IllegalStateException("Missing partition value for key: " + name);
    }
});

Type guard

boolean isCompletePartitionSpec(Map<String,String> spec, List<String> keys) {
    return keys.stream().allMatch(spec::containsKey);
}

Try / catch

try {
    // parse partition values
} catch (PrestoException e) {
    if (e.getErrorCode().getCode() == HIVE_INVALID_PARTITION_VALUE.toErrorCode().getCode()) {
        // drop and re-add the malformed partition
    } else throw e;
}

Prevention

When it happens

Trigger: A partition name string in the metastore that omits one of the table's declared partition key fields, so partitions.get(name) returns null during getMaterializedDataPredicates.

Common situations: Partitions created before a partition column was added; malformed partition directory names (missing a key=value component); metastore entries written by other tooling with incomplete partition specs.

Related errors


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