prestodb/presto · error · PrestoException
ICEBERG_BAD_DATA
ICEBERG_BAD_DATA
Error message
Failed to parse WKB geometry at position %d
What it means
When transforming blocks for updateable reads, transformGeometryBlock re-encodes WKB geometry values: it decodes each value with OGCGeometry.fromBinary and re-serializes it via EsriGeometrySerde. If any value fails to decode as valid WKB, the connector wraps the failure in ICEBERG_BAD_DATA, pointing at the offending row position.
Source
Thrown at presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergUpdateablePageSource.java:468
}
private Block transformGeometryBlock(Block block, Type type)
{
block = block.getLoadedBlock();
int positionCount = block.getPositionCount();
BlockBuilder builder = type.createBlockBuilder(null, positionCount);
for (int position = 0; position < positionCount; position++) {
if (block.isNull(position)) {
builder.appendNull();
}
else {
try {
OGCGeometry geometry = OGCGeometry.fromBinary(ByteBuffer.wrap(type.getSlice(block, position).getBytes()));
geometry.setSpatialReference(null);
type.writeSlice(builder, EsriGeometrySerde.serialize(geometry));
}
catch (Exception e) {
throw new PrestoException(ICEBERG_BAD_DATA, format("Failed to parse WKB geometry at position %d", position), e);
}
}
}
return builder.build();
}
private Block transformArrayBlock(Block block, ArrayType type)
{
block = block.getLoadedBlock();
Type elementType = type.getElementType();
ColumnarArray columnarArray = toColumnarArray(block);
Block transformedElements;
if (needDataTransform(elementType)) {
transformedElements = transformBlock(columnarArray.getElementsBlock(), elementType);
}
else {
return block;View on GitHub (pinned to 55bb57d202)
Solutions
- Locate and inspect the offending row (position is in the message) and fix or remove the malformed geometry at the source.
- Re-ingest the data with a tool that emits valid WKB (verify with ST_GeometryFromText/isValid checks upstream).
- If the column is not truly geometry, correct the table schema/column type mapping.
- Validate files after ingestion by scanning the geometry column in a read-only query before running UPDATEs.
Example fix
// before: raw bytes inserted into geometry column
INSERT INTO t VALUES (from_big_endian_64(...))
// after
INSERT INTO t VALUES (ST_AsBinary(ST_GeometryFromText('POINT(1 2)'))) Defensive patterns
Strategy: try-catch
Validate before calling
// validate geometry values upstream before writing
Slice wkb = ...;
try {
OGCGeometry.fromBinary(ByteBuffer.wrap(wkb.getBytes()));
} catch (Exception e) {
throw new IllegalArgumentException("Invalid WKB at ingestion", e);
} Try / catch
try {
rows = readUpdateableRows(...);
} catch (PrestoException e) {
if (e.getErrorCode() == ICEBERG_BAD_DATA.toErrorCode() &&
e.getMessage().contains("Failed to parse WKB geometry")) {
// quarantine/repair the file containing the malformed geometry, then retry
repairOrRewriteSourceFile();
rows = readUpdateableRows(...);
} else { throw e; }
} Prevention
- Write geometry columns only via ST_AsBinary or a trusted WKB writer
- Validate geometries (non-empty, correct SRID, parseable) at ingestion time
- Guard against schema drift so binary columns are not read as geometry
- Scan geometry columns in a read-only query after bulk ingestion to catch corruption early
When it happens
Trigger: A geometry column value in the data file is not valid WKB — truncated bytes, wrong endianness marker, non-geometry binary blob, or corrupt data written by another writer.
Common situations: Data ingested by external tools writing malformed geometries; schema drift where a binary column is being read as geometry; corrupted Parquet/ORC files after failed writes or storage issues.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/37b87233a994a2bb.
Report an issue: GitHub.