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
- Detect and skip 'BBOX EMPTY' (case-insensitive, trimmed) before fromWKT, treating it as absent.
- Normalize empty envelopes to Optional.empty()/null at compute time so they never reach the WKB sink.
- 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
- Map 'BBOX EMPTY' to Optional.empty()/null at compute time.
- Store envelopes as WKT if emptiness must be preserved.
- Use a shared empty-WKT filter across POINT/CIRCLE/BBOX.
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
- Empty POINT cannot be represented in WKB
- Empty CIRCLE cannot be represented in WKB
- Empty
- Unknown geometry type:
- holes must have the same number of dimensions as the polygon
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/751740debd78a704.
Report an issue: GitHub.