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

  1. Fix the JSON so keys are integer field ID strings.
  2. Regenerate the stats content with the same Iceberg version's writer.
  3. 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

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


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/be90ac93614ebef4. Report an issue: GitHub.