elastic/elasticsearch · error · IllegalArgumentException

Empty ENVELOPE cannot be represented in WKB

Error message

Empty ENVELOPE cannot be represented in WKB

What it means

writeWKBBBox (line 532) is the WKT-to-WKB direct converter for the BBOX/ENVELOPE type (ES extension, type 18). At line 539 it throws IllegalArgumentException when the token following 'BBOX' is 'EMPTY', because WKB bbox encoding requires minX, maxX, maxY, minY — an empty envelope has no extents. Note (line 542 TODO) 3D bbox is not yet supported here either.

Source

Thrown at libs/geo/src/main/java/org/elasticsearch/geometry/utils/WellKnownBinary.java:540

        // WKB circle format: type x y [z] r — z comes before radius
        writeInt(out, scratch, hasZ ? 1017 : 17);
        writeDouble(out, scratch, x);
        writeDouble(out, scratch, y);
        if (hasZ) {
            writeDouble(out, scratch, z);
        }
        writeDouble(out, scratch, r);
    }

    private static void writeWKBBBox(
        StreamTokenizer stream,
        ByteArrayOutputStream out,
        ByteBuffer scratch,
        boolean explicitZ,
        GeometryValidator validator
    ) throws IOException, ParseException {
        if (WellKnownText.nextEmptyOrOpen(stream).equals(WellKnownText.EMPTY)) {
            throw new IllegalArgumentException("Empty ENVELOPE cannot be represented in WKB");
        }
        // TODO: Add 3D bbox support (consistent with WellKnownText.parseBBox)
        double minX = WellKnownText.nextNumber(stream);
        WellKnownText.nextComma(stream);
        double maxX = WellKnownText.nextNumber(stream);
        WellKnownText.nextComma(stream);
        double maxY = WellKnownText.nextNumber(stream);
        WellKnownText.nextComma(stream);
        double minY = WellKnownText.nextNumber(stream);
        WellKnownText.nextCloser(stream);
        validator.validateBBox(minX, maxX, maxY, minY);
        validator.validateCoordinate(minX, minY, Double.NaN);
        validator.validateCoordinate(maxX, maxY, Double.NaN);
        WellKnownText.checkZorMAttribute(explicitZ, false);
        writeInt(out, scratch, 18);
        writeDouble(out, scratch, minX);
        writeDouble(out, scratch, maxX);
        writeDouble(out, scratch, maxY);

View on GitHub (pinned to db6a809a66)

Solutions

  1. Detect and skip 'BBOX EMPTY' (case-insensitive, trimmed) before fromWKT, treating it as absent.
  2. Normalize empty envelopes to Optional.empty()/null at compute time so they never reach the WKB sink.
  3. Store as WKT (which supports BBOX EMPTY) rather than WKB if emptiness must be preserved.

Example fix

// before
byte[] wkb = WellKnownBinary.fromWKT("BBOX EMPTY", BO, false, v); // throws

// after
String wkt = wktInput.trim();
if (wkt.equalsIgnoreCase("BBOX EMPTY")) {
    return null;
}
byte[] wkb = WellKnownBinary.fromWKT(wkt, BO, false, v);
Defensive patterns

Strategy: validation

Validate before calling

boolean isBboxEmpty(String wkt) {
    return wkt.trim().equalsIgnoreCase("BBOX EMPTY");
}

Type guard

static boolean isEmptyBboxWkt(String wkt) {
    return wkt.trim().equalsIgnoreCase("BBOX EMPTY");
}

Try / catch

try {
    return WellKnownBinary.fromWKT(wkt, bo, coerce, v);
} catch (IllegalArgumentException e) {
    if (wkt.trim().equalsIgnoreCase("BBOX EMPTY")) return null;
    throw e;
}

Prevention

When it happens

Trigger: Calling WellKnownBinary.fromWKT("BBOX EMPTY", byteOrder, coerce[, validator]) or any leading token the dispatcher routes to writeWKBBBox followed by EMPTY.

Common situations: Indexing envelope/bbox-shaped documents where the source represents absence as 'BBOX EMPTY'. Caching computed envelopes (some empty) and re-serializing to WKB. Ingest of WKT envelopes that occasionally carry EMPTY.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/751740debd78a704. Report an issue: GitHub.