{"record":{"id":"a55c4e80e6d3494e","repo":"prestodb/presto","slug":"iceberg-invalid-partition-value","errorCode":"ICEBERG_INVALID_PARTITION_VALUE","errorMessage":"Invalid partition value '%s' for %s partition key: %s","messagePattern":"Invalid partition value '(.+?)' for (.+?) partition key: (.+?)","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergUtil.java","lineNumber":954,"sourceCode":"                return parseLong(valueString);\n            }\n            if (type instanceof VarcharType) {\n                return utf8Slice(valueString);\n            }\n            if (type.equals(VarbinaryType.VARBINARY)) {\n                return wrappedBuffer(Base64.getDecoder().decode(valueString));\n            }\n            if (isShortDecimal(type) || isLongDecimal(type)) {\n                DecimalType decimalType = (DecimalType) type;\n                BigDecimal decimal = new BigDecimal(valueString);\n                decimal = decimal.setScale(decimalType.getScale(), BigDecimal.ROUND_UNNECESSARY);\n                checkArgument(decimal.precision() <= decimalType.getPrecision());\n                BigInteger unscaledValue = decimal.unscaledValue();\n                return isShortDecimal(type) ? unscaledValue.longValue() : Decimals.encodeUnscaledValue(unscaledValue);\n            }\n        }\n        catch (IllegalArgumentException e) {\n            throw new PrestoException(ICEBERG_INVALID_PARTITION_VALUE, format(\n                    \"Invalid partition value '%s' for %s partition key: %s\",\n                    valueString,\n                    type.getDisplayName(),\n                    name));\n        }\n        // Iceberg tables don't partition by non-primitive-type columns.\n        throw new PrestoException(GENERIC_INTERNAL_ERROR, \"Invalid partition type \" + type.toString());\n    }\n\n    public static Domain createDomainFromIcebergPartitionValue(\n            Object value,\n            org.apache.iceberg.types.Type icebergType,\n            Type prestoType)\n    {\n        if (value == null) {\n            return onlyNull(prestoType);\n        }\n","sourceCodeStart":936,"sourceCodeEnd":972,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergUtil.java#L936-L972","documentation":"IcebergUtil.deserializeIcebergValue parses the string-encoded partition value from Iceberg partition metadata into a Presto value of the column's type. When parsing fails (a thrown IllegalArgumentException from parseLong/parseFloat/parseDouble/Base64 decoding, BigDecimal construction, setScale with ROUND_UNNECESSARY, or a precision checkArgument), the code rethrows it as a PrestoException with code ICEBERG_INVALID_PARTITION_VALUE. This indicates the stored partition value string does not match the declared partition key type, i.e. table metadata is inconsistent or the value is out of the expected format/range.","triggerScenarios":"Reading/deserializing Iceberg partition values during table scan when a partition value string cannot be converted: non-numeric text for an integer/bigint key, malformed boolean (not 'true'/'false'), non-Base64 binary, decimal string whose scale cannot be set without rounding, or a decimal whose precision exceeds the column's declared precision.","commonSituations":"Tables written by external engines (Spark/Flink) with differently formatted partition values; schema evolution that changed a partition column type after data was written; manually edited or corrupted metadata; DECIMAL partition columns where written values have more precision than declared; timestamp/time keys whose epoch value strings are corrupt.","solutions":["Inspect the table's partition metadata (e.g. via Iceberg metadata files or Spark) to find the offending partition key and value and verify it parses as the declared type","Check whether the partition column type was evolved (ALTER) after data was written; rewrite/repair the affected partitions so values match the current schema","Verify DECIMAL partition keys: values must have exactly the declared scale and not exceed the declared precision","If the table was written by an incompatible engine version, rewrite the table metadata with a compatible writer (e.g. rewrite_data_files / migrate) or upgrade the connector","File/inspect the table as an external table only after fixing metadata; as a workaround, exclude the corrupt partition from the query predicate"],"exampleFix":"// before: partition value string '3.14159' on DECIMAL(4,2) key\ndecimal = new BigDecimal(\"3.14159\").setScale(2, ROUND_UNNECESSARY); // throws IllegalArgumentException -> ICEBERG_INVALID_PARTITION_VALUE\n// after: repair the partition metadata so the stored value matches DECIMAL(4,2)\n// e.g. rewrite the partition so the stored value is '3.14' (scale-2, precision <= 4)","handlingStrategy":"validation","validationCode":"// Validate a partition value string before it reaches the connector\nboolean isValidPartitionValue(String valueString, presto.spi.type.Type type) {\n    if (valueString == null) return true;\n    try {\n        if (type.equals(BooleanType.BOOLEAN)) return valueString.equalsIgnoreCase(\"true\") || valueString.equalsIgnoreCase(\"false\");\n        if (type.equals(BigintType.BIGINT) || type.equals(IntegerType.INTEGER) || type.equals(DateType.DATE)) Long.parseLong(valueString);\n        else if (type.equals(RealType.REAL) || type.equals(DoubleType.DOUBLE)) Double.parseDouble(valueString);\n        else if (type instanceof DecimalType) {\n            DecimalType dt = (DecimalType) type;\n            java.math.BigDecimal d = new java.math.BigDecimal(valueString).setScale(dt.getScale(), java.math.BigDecimal.ROUND_UNNECESSARY);\n            if (d.precision() > dt.getPrecision()) return false;\n        }\n        else if (type.equals(VarbinaryType.VARBINARY)) java.util.Base64.getDecoder().decode(valueString);\n        return true;\n    } catch (RuntimeException e) { return false; }\n}","typeGuard":"boolean isParsableAsLong(String s) {\n    try { Long.parseLong(s); return true; } catch (NumberFormatException e) { return false; }\n}","tryCatchPattern":"try {\n    session.execute(query);\n} catch (QueryFailedException e) {\n    if (e.getErrorCode() == ICEBERG_INVALID_PARTITION_VALUE) {\n        // skip/repair the offending partition; don't retry blindly\n    } else throw e;\n}","preventionTips":["Keep partition column types primitive and stable; avoid evolving partition column types after writes","Validate DECIMAL partition keys: written values must match declared scale and precision exactly","Write Iceberg tables only with engines whose writer versions format partition values compatibly","Audit partition metadata after external writes or manual metadata edits"],"tags":["iceberg","partitioning","metadata","parsing"],"backgroundTag":"invalid-partition-value","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"}