OtterMind/Chat2DB · info · IllegalArgumentException

EWKB contains a negative element count

Error message

EWKB contains a negative element count

What it means

Thrown by PostgreSQLGeometryProcessor.readCount when a 4-byte integer read from the EWKB byte stream is negative. This count represents the number of coordinates, rings, or child geometries depending on context. Negative counts are structurally impossible in valid EWKB. readCount is called from inspectLineString, inspectLinearRing (ring coordinate count), inspectGeometry (polygon ring count at line 203), and inspectChildren (child count at line 278). The exception is caught by convertJDBCValueByType at line 80 and the raw hex value is returned gracefully.

Source

Thrown at chat2db-community-server/chat2db-community-plugins/chat2db-community-postgresql/src/main/java/ai/chat2db/plugin/postgresql/value/sub/PostgreSQLGeometryProcessor.java:294

    private void inspectChildren(WkbCursor cursor, ByteOrder byteOrder, WkbHeader parent,
                                 Integer inheritedSrid, int expectedType, int depth) {
        int childCount = readCount(cursor, byteOrder);
        Integer effectiveSrid = parent.srid() != null ? parent.srid() : inheritedSrid;
        for (int i = 0; i < childCount; i++) {
            WkbHeader child = inspectGeometry(cursor, effectiveSrid, false, depth + 1);
            if (expectedType != 0 && child.baseType() != expectedType) {
                throw new IllegalArgumentException("EWKB collection contains an unexpected geometry type");
            }
            if (child.hasZ() != parent.hasZ() || child.hasMeasure() != parent.hasMeasure()) {
                throw new IllegalArgumentException("EWKB collection contains mixed coordinate dimensions");
            }
        }
    }

    private int readCount(WkbCursor cursor, ByteOrder byteOrder) {
        int count = cursor.readInt(byteOrder);
        if (count < 0) {
            throw new IllegalArgumentException("EWKB contains a negative element count");
        }
        return count;
    }

    private ByteOrder readByteOrder(WkbCursor cursor) {
        int byteOrder = cursor.readUnsignedByte();
        if (byteOrder == 0) {
            return ByteOrder.BIG_ENDIAN;
        }
        if (byteOrder == 1) {
            return ByteOrder.LITTLE_ENDIAN;
        }
        throw new IllegalArgumentException("Unsupported EWKB byte order");
    }

    private String removeTypeParenthesisSpace(String wkt) {
        int openParenthesis = wkt.indexOf('(');
        if (openParenthesis > 0 && wkt.charAt(openParenthesis - 1) == ' ') {

View on GitHub (pinned to 5ee1e990e7)

Solutions

  1. No action required in production — convertJDBCValueByType catches this and returns the raw hex value
  2. Hex-dump the EWKB to verify count fields are valid unsigned values
  3. Re-import the geometry from a trusted source

Example fix

// before: EWKB count field bytes decode to a negative int (corrupt)
// after: ensure count fields contain valid non-negative integers in the correct byte order
Defensive patterns

Strategy: try-catch

Validate before calling

// Already caught in convertJDBCValueByType. For EWKB integrity:
// Verify count fields are non-negative before trusting the binary structure.
// This is inherent to valid EWKB; corrupt data is the only trigger.

Try / catch

try {
    int count = readCount(cursor, byteOrder);
} catch (IllegalArgumentException e) {
    log.debug("EWKB negative count", e);
    return value;
}

Prevention

When it happens

Trigger: Parsing EWKB where any count field (coordinate count, ring count, or child count) is a negative 4-byte signed integer. readCount at line 292 reads via cursor.readInt and checks count < 0.

Common situations: Truncated or corrupt binary data where byte patterns decode to negative integers; endianness mismatch causing bytes to be misinterpreted; bit-flipped data in storage.

Related errors


AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14). Data as JSON: /api/errors/f13d22e4e6d10d1f. Report an issue: GitHub.