apache/iceberg · error · IllegalArgumentException
Invalid field ID for content stats: %s
Error message
Invalid field ID for content stats: %s
What it means
ContentFileParser.fromJson parses content-stats field IDs from JSON where keys are numeric field ID strings. parseFieldId converts each key to an int; a non-numeric key means the JSON is malformed for this format, so an IllegalArgumentException with the offending string is thrown.
Source
Thrown at core/src/main/java/org/apache/iceberg/ContentFileParser.java:354
Preconditions.checkArgument(
fieldStats != null && fieldStats.isObject(),
"Cannot parse content stats for field %s from non-object: %s",
fieldId,
fieldStats);
Integer avgValueSize = JsonUtil.getIntOrNull(AVG_VALUE_SIZE_IN_BYTES, fieldStats);
if (avgValueSize != null) {
avgValueSizes.put(parseFieldId(fieldId), avgValueSize);
}
}
return avgValueSizes.isEmpty() ? null : avgValueSizes;
}
private static int parseFieldId(String fieldId) {
try {
return Integer.parseInt(fieldId);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(
String.format("Invalid field ID for content stats: %s", fieldId), e);
}
}
private static void partitionToJson(
Types.StructType partitionType, StructLike partitionData, JsonGenerator generator)
throws IOException {
generator.writeStartArray();
List<Types.NestedField> fields = partitionType.fields();
for (int pos = 0; pos < fields.size(); ++pos) {
Types.NestedField field = fields.get(pos);
Object partitionValue = partitionData.get(pos, Object.class);
SingleValueParser.toJson(field.type(), partitionValue, generator);
}
generator.writeEndArray();
}
private static PartitionData partitionFromJson(View on GitHub (pinned to 86d9c8fc54)
Solutions
- Fix the JSON so keys are integer field ID strings.
- Regenerate the stats content with the same Iceberg version's writer.
- Verify which producer wrote the JSON and align its key format with the Iceberg content-stats spec.
Example fix
// before
{"row_count": 100, "column_sizes": {"id": 16}}
// after
{"row_count": 100, "column_sizes": {"1": 16}} Defensive patterns
Strategy: validation
Validate before calling
boolean allNumeric = jsonObject.keySet().stream().allMatch(k -> k.matches("\\d+"));
if (!allNumeric) throw new IllegalArgumentException("stats keys must be field IDs"); Try / catch
try { ContentFileParser.fromJson(...); } catch (IllegalArgumentException e) {
LOG.error("bad field ID: {}", e.getMessage());
throw e;
} Prevention
- Always serialize stats with ContentFileParser.toJson.
- Use field IDs, never column names, as JSON keys.
- Pin producer/consumer to the same Iceberg version.
When it happens
Trigger: Calling ContentFileParser.fromJson (for content stats / avg value sizes) on JSON whose field-ID keys are not numeric strings, e.g. column names instead of IDs.
Common situations: Hand-written or third-party-produced stats JSON using column names as keys; mixing specs/versions that serialize stats differently; copy-paste edits of stats JSON.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Invalid partition data for content file: expected array or o
- Invalid file content value: '%s'
- Unknown task type:
- Cannot parse default as a %s value: %s
- Cannot parse to a duration string value: %s: %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/be90ac93614ebef4.
Report an issue: GitHub.