What happens?
ST_Union_Agg followed by an INSERT … SELECT into a table with a GEOMETRY column (then CHECKPOINT) intermittently corrupts the
transaction on a persistent on‑disk database, throwing:
Invalid Input Error: Skipping beyond end of binary data at position 16
The error then recurs during the automatic rollback, which escalates to a fatal, connection‑killing state:
FATAL Error: Failed to rollback transaction. Cannot continue operation.
It is non‑deterministic: running the exact same script on the exact same data fails at a different GROUP BY partition each time. There is ample free RAM and no disk spilling when it happens. This is a regression in 1.5.x — the identical script on the identical database file completes with no error on 1.4.4, but fails on 1.5.3 (same OS, hardware, data, client, and glibc malloc). Smaller per‑row geometries (e.g. writing the ~32M un‑aggregated input polygons) write fine; only the large aggregated multipolygons produced by
ST_Union_Agg trigger it.
To Reproduce
The failure occurs on a ~32 M‑row spatial dataset and is data‑dependent and intermittent, so I have not yet been able to distill a data‑independent minimal example (a synthetic generator producing ~6,900‑vertex unions did not trigger it). The exact, faithful reproducer:
import duckdb
# postcodes.duckdb (~7 GB) contains one table:
# voronoi_raw(postcode VARCHAR, region_code VARCHAR(2), voronoi_geom GEOMETRY)
# ~32.2M rows: a Voronoi tessellation of UK address points
# ~1.75M distinct postcodes spread across 11 region_code values
con = duckdb.connect("postcodes.duckdb")
con.execute("LOAD spatial;")
con.execute("SET threads=4;") # also fails at threads=23
con.execute("SET memory_limit='31GB';") # no disk spill occurs; RAM is not exhausted
con.execute("""
CREATE TABLE voronoi_unioned (
postcode VARCHAR PRIMARY KEY,
region_code VARCHAR(2),
unioned_geom GEOMETRY,
cell_count INTEGER,
area_m2 DOUBLE
)
""")
# Union the cells of each postcode into one geometry, one region per INSERT.
for (region,) in con.execute(
"SELECT DISTINCT region_code FROM voronoi_raw ORDER BY 1"
).fetchall():
con.execute(f"""
INSERT INTO voronoi_unioned
SELECT postcode, region_code, unioned_geom, cell_count, ST_Area(unioned_geom)
FROM (
SELECT postcode, region_code,
ST_Union_Agg(voronoi_geom) AS unioned_geom,
COUNT(*) AS cell_count
FROM voronoi_raw
WHERE region_code = '{region}'
GROUP BY postcode, region_code
)
WHERE unioned_geom IS NOT NULL
""")
con.execute("CHECKPOINT;")
print(region, "ok")
Output (the partition at which it dies varies run‑to‑run, e.g. NE one run, WA the next):
EE ok
EM ok
LN ok
duckdb.duckdb.FatalException: FATAL Error: Failed to rollback transaction. Cannot continue operation.
Original Error: Invalid Input Error: Skipping beyond end of binary data at position 16
Rollback Error: Invalid Input Error: Skipping beyond end of binary data at position 16
The same script against the same file on DuckDB 1.4.4 completes all 11 partitions with no error:
EE ok
EM ok
LN ok
NE ok
NW ok
SC ok
SE ok
SW ok
WA ok
WM ok
YH ok
The failing operation is plain SQL (ST_Union_Agg + INSERT + CHECKPOINT), so it should reproduce from the DuckDB CLI as well; I have only reproduced it via the Python client
against this dataset and have not isolated a data‑independent CLI script.
OS:
Ubuntu 24.04.4 LTS (Linux 6.17.0‑35‑generic, x86_64)
DuckDB Version:
1.5.3 (regression); 1.4.4 works correctly
DuckDB Client:
Python client (duckdb PyPI wheel), Python 3.12.3; spatial extension b68b309
Hardware:
AMD Ryzen 9 3900X (12C/24T), 62 GiB RAM (~49 GiB free during the run), NVMe SSD
Full Name:
Matt Duggan
Affiliation:
skutter.ai
Did you include all relevant configuration (e.g., CPU architecture, Linux distribution) to reproduce the issue?
Did you include all code required to reproduce the issue?
Did you include all relevant data sets for reproducing the issue?
Yes
What happens?
ST_Union_Agg followed by an INSERT … SELECT into a table with a GEOMETRY column (then CHECKPOINT) intermittently corrupts the
transaction on a persistent on‑disk database, throwing:
Invalid Input Error: Skipping beyond end of binary data at position 16
The error then recurs during the automatic rollback, which escalates to a fatal, connection‑killing state:
FATAL Error: Failed to rollback transaction. Cannot continue operation.
It is non‑deterministic: running the exact same script on the exact same data fails at a different GROUP BY partition each time. There is ample free RAM and no disk spilling when it happens. This is a regression in 1.5.x — the identical script on the identical database file completes with no error on 1.4.4, but fails on 1.5.3 (same OS, hardware, data, client, and glibc malloc). Smaller per‑row geometries (e.g. writing the ~32M un‑aggregated input polygons) write fine; only the large aggregated multipolygons produced by
ST_Union_Agg trigger it.
To Reproduce
The failure occurs on a ~32 M‑row spatial dataset and is data‑dependent and intermittent, so I have not yet been able to distill a data‑independent minimal example (a synthetic generator producing ~6,900‑vertex unions did not trigger it). The exact, faithful reproducer:
Output (the partition at which it dies varies run‑to‑run, e.g. NE one run, WA the next):
The same script against the same file on DuckDB 1.4.4 completes all 11 partitions with no error:
The failing operation is plain SQL (ST_Union_Agg + INSERT + CHECKPOINT), so it should reproduce from the DuckDB CLI as well; I have only reproduced it via the Python client
against this dataset and have not isolated a data‑independent CLI script.
OS:
Ubuntu 24.04.4 LTS (Linux 6.17.0‑35‑generic, x86_64)
DuckDB Version:
1.5.3 (regression); 1.4.4 works correctly
DuckDB Client:
Python client (duckdb PyPI wheel), Python 3.12.3; spatial extension b68b309
Hardware:
AMD Ryzen 9 3900X (12C/24T), 62 GiB RAM (~49 GiB free during the run), NVMe SSD
Full Name:
Matt Duggan
Affiliation:
skutter.ai
Did you include all relevant configuration (e.g., CPU architecture, Linux distribution) to reproduce the issue?
Did you include all code required to reproduce the issue?
Did you include all relevant data sets for reproducing the issue?
Yes