You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
SIGSEGV on querying using multiple connections #435
Concurrently querying select 1 for 8 DuckDBPyConnections, one in each thread, segfaults.
To Reproduce
Minimal reproduction:
import concurrent.futures
import faulthandler
import duckdb
faulthandler.enable()
conns = [duckdb.connect() for _ in range(8)]
def run(i):
conns[i % 8].execute('SELECT 1').fetchall()
with concurrent.futures.ThreadPoolExecutor(8) as ex:
for f in [ex.submit(run, i) for i in range(200)]:
try: f.result()
except Exception as e: print(f'{type(e).__name__}: {e}')
Expected output:
Empty, exit code 0
Actual output
RuntimeError: Could not allocate tuple object!
Fatal Python error: Segmentation fault
System: mac arm64, python3.12, duckdb 1.5.2
Also reproducible on a railway env with python 3.13, linux x86-64, duckdb 1.5.2
OS:
aarch64
DuckDB Version:
1.5.2
DuckDB Client:
1.5.2
Hardware:
No response
Full Name:
David He
Affiliation:
Intercept
Did you include all relevant configuration (e.g., CPU architecture, Linux distribution) to reproduce the issue?
Yes, I have
Did you include all code required to reproduce the issue?
Yes, I have
Did you include all relevant data sets for reproducing the issue?
Not applicable - the reproduction does not require a data set
Hey @dhe128, thanks for the report. The segfault should definitely not happen, I put up #462 for that.
However, it's not possible to re-use connections across threads. You can create cursors from a connection and use those:
import concurrent.futures
import faulthandler
import duckdb
faulthandler.enable()
conns = [duckdb.connect() for _ in range(8)]
def run(i):
conns[i % 8].cursor().execute('SELECT 1').fetchall()
with concurrent.futures.ThreadPoolExecutor(8) as ex:
for f in [ex.submit(run, i) for i in range(200)]:
try: f.result()
except Exception as e: print(f'{type(e).__name__}: {e}')
This would work with a single connection as well, btw:
import concurrent.futures
import faulthandler
import duckdb
faulthandler.enable()
conn = duckdb.connect()
def run(i):
conn.cursor().execute('SELECT 1').fetchall()
with concurrent.futures.ThreadPoolExecutor(8) as ex:
for f in [ex.submit(run, i) for i in range(200)]:
try: f.result()
except Exception as e: print(f'{type(e).__name__}: {e}')
Activity
[-]SIGSEGV on quering parquet file from multiple connections[/-][+]SIGSEGV on querying using multiple connections[/+]evertlammerts commentedon May 18, 2026
Hey @dhe128, thanks for the report. The segfault should definitely not happen, I put up #462 for that.
However, it's not possible to re-use connections across threads. You can create cursors from a connection and use those:
This would work with a single connection as well, btw:
Use recursive mutex to deal with GIL <-> internal lock deadlocks (#462)