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

  1. Locate and inspect the offending row (position is in the message) and fix or remove the malformed geometry at the source.
  2. Re-ingest the data with a tool that emits valid WKB (verify with ST_GeometryFromText/isValid checks upstream).
  3. If the column is not truly geometry, correct the table schema/column type mapping.
  4. 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

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

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/37b87233a994a2bb. Report an issue: GitHub.