apache/iceberg · error · InvalidWkbException

Invalid WKB: expected dimensions %s but found %s

Error message

Invalid WKB: expected dimensions %s but found %s

What it means

ISO WKB encodes dimensions (XY, XYZ, XYM, XYZM) in the thousands digit of the type code. When building geometry bounds for a column with a known dimension, a value whose dimension group differs from the expected one is rejected with InvalidWkbException, because a Z or M variant does not match the column's declared geometry dimension. addValue catches this and suppresses the file's bounds rather than failing the write.

Source

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

    // 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) {
      case TYPE_POINT -> readCoordinate(buffer, numDimensions);
      case TYPE_LINE_STRING -> readCoordinateSequence(buffer, numDimensions);
      case TYPE_POLYGON -> readPolygon(buffer, numDimensions);
      case TYPE_MULTI_POINT -> readCollection(buffer, TYPE_POINT, dimensionGroup);
      case TYPE_MULTI_LINE_STRING -> readCollection(buffer, TYPE_LINE_STRING, dimensionGroup);
      case TYPE_MULTI_POLYGON -> readCollection(buffer, TYPE_POLYGON, dimensionGroup);
      case TYPE_GEOMETRY_COLLECTION -> readCollection(buffer, ANY_GEOMETRY, dimensionGroup);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Make the writer emit values matching the column's declared dimension (drop Z/M or update the column type).
  2. Rewrite inconsistent files so all values share the column's dimension.
  3. Check the geometry type code's thousands digit of the failing value to confirm the dimension mismatch.
  4. If bounds silently disappear, find the offending file and normalize its geometry values.

Example fix

// before
// column expects XY but value carries Z (type code 1001 = Z point)
builder.addValue(pointWithZWkb);
// after
Geometry pt = pointWithZ.dropZ(); // re-encode as 2D WKB
builder.addValue(pt.toWkb());
Defensive patterns

Strategy: validation

Validate before calling

static int wkbDimensionGroup(ByteBuffer wkb) {
  int type = wkb.getInt(wkb.position() + 1); // skip order byte
  return type / 1000; // 0=XY 1=XYZ 2=XYM 3=XYZM
}
// compare against the column's declared dimension before writing

Type guard

boolean matchesExpectedDimension(ByteBuffer wkb, int expectedGroup) {
  return wkb != null && wkb.remaining() >= 5 && wkbDimensionGroup(wkb) == expectedGroup;
}

Prevention

When it happens

Trigger: Parsing a geometry whose dimension group (typeCode/1000) differs from expectedDimension, e.g. an XYZ (Z=1) or XYM (M=2) value written into a column expected to be plain XY, or a mismatch between members of a multi-geometry.

Common situations: Schema changed from GEOMETRY(XY) to GEOMETRY(Z) (or vice versa) without rewriting old files; a writer emits Z coordinates while the column metadata says 2D; mixed-dimensional values from upstream GIS tools.

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/1fc8a5e29cd6f171. Report an issue: GitHub.