apache/iceberg · error · InvalidWkbException

Invalid WKB: expected geometry type %s but found %s

Error message

Invalid WKB: expected geometry type %s but found %s

What it means

When parsing WKB for geometry bounds, a nested element of a multi-geometry or geometry collection must match the parent's declared member type (and the column's expected type). If the parsed geometry type differs from the expected type, the bytes are structurally inconsistent with WKB/Parquet typing rules and InvalidWkbException is thrown. Like all InvalidWkb exceptions in this builder, addValue catches it and suppresses bounds for the file instead of failing the write.

Source

Thrown at core/src/main/java/org/apache/iceberg/GeometryBoundsBuilder.java:170

  }

  private void parseGeometryBodyAndUpdateBound(
      ByteBuffer buffer, int expectedType, int expectedDimension) {
    long typeCode = Integer.toUnsignedLong(buffer.getInt());
    int dimensionGroup = (int) (typeCode / DIMENSION_DIVISOR);
    int geometryType = (int) (typeCode % DIMENSION_DIVISOR);
    // only the seven OGC types in XY/XYZ/XYM/XYZM are bounded here; other valid OGC types (such as
    // PolyhedralSurface, TIN, and Triangle) are unsupported and cost the value its bounds
    checkWkb(
        geometryType >= TYPE_POINT
            && geometryType <= TYPE_GEOMETRY_COLLECTION
            && dimensionGroup <= XYZM_GROUP,
        "Invalid or unsupported WKB geometry type: %s",
        typeCode);
    // an element of a multi geometry or collection must match its parent's member type and
    // dimensions; if/throw so the message is built only when a value is actually rejected
    if (expectedType != ANY_GEOMETRY && geometryType != expectedType) {
      throw new InvalidWkbException(
          "Invalid WKB: expected geometry type "
              + typeName(expectedType)
              + " but found "
              + typeName(geometryType));
    }
    if (expectedDimension != ANY_DIMENSION && dimensionGroup != expectedDimension) {
      throw new InvalidWkbException(
          "Invalid WKB: expected dimensions "
              + dimensionName(expectedDimension)
              + " but found "
              + dimensionName(dimensionGroup));
    }

    int numDimensions = numDimensions(dimensionGroup);

    // checkWkb above already constrained geometryType to the seven OGC types, so no default arm
    // is reachable here
    switch (geometryType) {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Ensure every geometry value in a column matches the column's declared geometry type (e.g. don't mix points and polygons).
  2. Regenerate bounds/data with a conformant writer if types were mixed by an older tool.
  3. Inspect the failing geometry's 4-byte type code to confirm what was actually stored.
  4. If the error is caught internally (missing bounds only), locate the offending file and rewrite its geometry column.

Example fix

// before
// column declared POINT, but value is a LineString WKB (type 2)
builder.addValue(lineStringWkb);
// after
builder.addValue(pointWkb); // type code 1 matches expected POINT
Defensive patterns

Strategy: validation

Validate before calling

static int wkbType(ByteBuffer wkb) {
  int type = wkb.getInt(wkb.position() + 1); // skip order byte
  return type % 1000; // strip dimension thousands digit
}
// verify wkbType equals the column's expected geometry type before writing

Type guard

boolean matchesExpectedType(ByteBuffer wkb, int expectedType) {
  return wkb != null && wkb.remaining() >= 5 && wkbType(wkb) == expectedType;
}

Prevention

When it happens

Trigger: Parsing a geometry whose declared type code (after masking the dimension thousands digit) does not match the expected column type, e.g. a MULTIPOINT value stored in a column whose bounds are built with expectedType=POINT, or a heterogeneous geometry collection where members differ from the parent's type.

Common situations: Mixed geometry types written into one column where per-column type tracking says otherwise; hand-crafted or corrupted WKB; writers that emit geometry collections where the schema promises a specific type.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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