SIGBUS in ddbc_bindings.Connection on 1.7.1 (macOS arm64) when authenticating with SQL_COPT_SS_ACCESS_TOKEN against Fabric DW · Issue #594 · microsoft/mssql-python · GitHub
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
SIGBUS in ddbc_bindings.Connection on 1.7.1 (macOS arm64) when authenticating with SQL_COPT_SS_ACCESS_TOKEN against Fabric DW #594
On mssql-python 1.7.1 (macOS 26.3.1 arm64, Python 3.13.7), calling mssql_python.connect() with an Azure access token supplied via attrs_before / SQL_COPT_SS_ACCESS_TOKEN (1256) against a real Microsoft Fabric Data Warehouse crashes the host Python interpreter with SIGBUS (Bus error: 10). No Python exception is raised, no traceback is emitted — the process is terminated by the kernel after the TCP/TLS handshake completes and the access-token authentication exchange begins.
The same script works correctly on 1.4.0, 1.5.0, and 1.6.0 from the same machine against the same warehouse.
faulthandler pins the fault to the native ddbc_bindings.Connection(...) call:
Fatal Python error: Bus error
Current thread 0x00000001ef8eb100 (most recent call first):
File ".../mssql_python/connection.py", line 374 in __init__
File ".../mssql_python/db_connection.py", line 55 in connect
File ".../repro_mssql_python_bus_error.py", line 65 in main
Extension modules: _cffi_backend (total: 1)
connection.py:374 is the self._conn = ddbc_bindings.Connection(self.connection_str, self._pooling, self._attrs_before) call.
Scope (bisect)
Tested against the same Fabric DW endpoint, same Python, same machine:
Variant
1.4.0
1.5.0
1.6.0
1.7.1
connect() + attrs_before (SQL_COPT_SS_ACCESS_TOKEN) + real Fabric DW
✅ Connected, SELECT 1 round-trips
✅
✅
❌ SIGBUS
connect() without attrs_before + fake server
n/a
n/a
✅ raises RuntimeError
✅ raises OperationalError
connect() with attrs_before (bogus token bytes) + fake server
n/a
n/a
✅ raises RuntimeError
✅ raises OperationalError
So the crash requires all of: 1.7.1, a real server that completes the TLS handshake, and attrs_before carrying SQL_COPT_SS_ACCESS_TOKEN. It is not triggered by argument-parsing of attrs_before alone, and it is not triggered without attrs_before even when the server is real. Smells like the bug lives in the token-auth handshake path in the native ddbc layer.
1.7.0 was not testable on macOS arm64 / Python 3.13.7 because no wheel was published for that platform (see #588). I cannot confirm whether 1.7.0 has the same fault.
To reproduce
Prereqs: a Microsoft Fabric workspace with a Data Warehouse, and az login against the right tenant.
Expected on 1.7.1: stops after Calling mssql_python.connect() ..., kernel kills the process with Bus error: 10 and a multiprocessing semaphore leak warning. No Python traceback.
Expected on 1.6.0: prints Connected. and Round-trip select returned: (1,).
Expected behavior
mssql_python.connect() with attrs_before={SQL_COPT_SS_ACCESS_TOKEN: ...} against Fabric DW should either succeed (as on 1.6.0) or raise a Python exception (OperationalError, DatabaseError, etc.). It must not terminate the host process.
Further technical details
mssql-python version: 1.7.1 (uploaded 2026-05-20T15:23, same day as the bug surfaced downstream)
Python version: 3.13.7
SQL Server version: Microsoft Fabric Data Warehouse (SQL endpoint at *.datawarehouse.fabric.microsoft.com)
This is likely happening due to the stack local copy of the Access Token. ODBC expects the memory address of the Access Token buffer to be retained for all the connections.
The violation of this requirement from ODBC in the PR #568 is what is causing the problem.
I will own the bug since the culprit regression is due to my changes.
I think during the PR review, I remember that Linux likely has the stacklocal copy and I am wondering why Linux doesn't repro this problem.
This is likely happening due to the stack local copy of the Access Token. ODBC expects the memory address of the Access Token buffer to be retained for all the connections. The violation of this requirement from ODBC in the PR #568 is what is causing the problem.
I will own the bug since the culprit regression is due to my changes.
I think during the PR review, I remember that Linux likely has the stacklocal copy and I am wondering why Linux doesn't repro this problem.
Corroborating report - same 1.7.1 token-auth regression on Windows and Linux
Same 1.7.1 regression as #594, reproduced on two more platforms. With macOS (#594) + Windows + Linux all affected, this is clearly not platform-specific.
Posting here rather than opening a new issue since the trigger is identical (SQL_COPT_SS_ACCESS_TOKEN via attrs_before, 1.7.1 only) - happy to split if you'd prefer.
Details
Controlled A/B repro: Windows 11 x64, Python 3.13 - mssql-python 1.7.1, pyodbc 5.3.0 (control), ODBC Driver 18 for SQL Server.
Production: Azure Functions on Linux - mssql-python 1.7.1. This is what originally bit us: auth failures on a deployed service after a routine deploy pulled 1.7.1.
Backend in both cases: Azure SQL Database (not Fabric DW).
Auth: Entra ID access token via attrs_before={1256: token_struct}.
Symptom
Unlike #594's SIGBUS on macOS arm64, on Windows and Linux the driver does not crash - it raises Python exceptions, but connect() fails. Two error signatures, both from ddbc_bindings.Connection:
Driver Error: Invalid authorization specification;
DDBC Error: [Microsoft][SQL Server]Login failed for user '<token-identified principal>'.
Driver Error: Communication link failure;
DDBC Error: [Microsoft]TCP Provider: An existing connection was forcibly
closed by the remote host. (Error code 0x2746 / WSAECONNRESET)
Verbatim from Azure Functions on Linux (production, 2026-05-20 13:04:49 UTC, mssql-python 1.7.1):
sqlalchemy.exc.OperationalError: (mssql_python.exceptions.OperationalError)
Driver Error: Communication link failure;
DDBC Error: [Microsoft]TCP Provider: Error code 0x2746
The token is valid - A/B against pyodbc with the same token bytes
I acquire one access token, pack it once into the standard SQL Server token struct, and feed the identical bytes to both drivers in a loop:
Same token struct, same server, same machine, same moment: pyodbc 8/8, mssql-python 1.7.1 0/8. Note 0x2746 is normally a transient network fault - but pyodbc, fed the identical token at the same instant, got zero of them. So under 1.7.1 this is not a transient; the access-token connect path is broken. The token and the database grant are demonstrably fine. Consistent with #594, this works on 1.6.0; only 1.7.1 fails.
Reproduce
importstructimportmssql_pythonimportpyodbcfromazure.identityimportDefaultAzureCredentialSERVER="<server>.database.windows.net"DATABASE="<database>"SQL_COPT_SS_ACCESS_TOKEN=1256# One Entra ID access token, packed into the standard SQL Server token struct.raw=DefaultAzureCredential().get_token("https://database.windows.net/.default").tokentoken_utf16=raw.encode("utf-16-le")
token_struct=struct.pack("<I", len(token_utf16)) +token_utf16base=f"Server=tcp:{SERVER},1433;Database={DATABASE};Encrypt=yes;TrustServerCertificate=no;"defattempt(label, connect):
ok=0for_inrange(8):
try:
c=connect()
c.cursor().execute("SELECT 1")
c.close()
ok+=1exceptExceptionase:
print(f" {label} FAIL: {type(e).__name__}: {e}")
print(f"{label}: {ok}/8 succeeded\n")
# Identical token_struct fed to both drivers:attempt("mssql-python 1.7.1", lambda: mssql_python.connect(
base, attrs_before={SQL_COPT_SS_ACCESS_TOKEN: token_struct}))
attempt("pyodbc", lambda: pyodbc.connect(
"Driver={ODBC Driver 18 for SQL Server};"+base,
attrs_before={SQL_COPT_SS_ACCESS_TOKEN: token_struct}))
Matchesthe"isolated to the native token authentication handshake path introduced in 1.7.1"finding-anditreproducesonmacOS, Windows, andLinux (macOS → SIGBUS, Windows/Linux → handshakefails → serverrejectsthetoken/TCPRST0x2746). HappytocaptureDDBC/ODBCtracelogsortestapatch.
Activity
github-actions commentedon May 20, 2026
Hi Sam Debruyn (@sdebruyn), thank you for opening this issue!
Our team will review it shortly. We aim to triage all new issues within 24-48 hours and get back to you.
If you have additional information to share, please feel free to update the issue.
Thank you for your patience!
saurabh500 commentedon May 20, 2026
This is likely happening due to the stack local copy of the Access Token. ODBC expects the memory address of the Access Token buffer to be retained for all the connections.
The violation of this requirement from ODBC in the PR #568 is what is causing the problem.
I will own the bug since the culprit regression is due to my changes.
I think during the PR review, I remember that Linux likely has the stacklocal copy and I am wondering why Linux doesn't repro this problem.
Sam Debruyn (@sdebruyn) is this repro on Linux or Windows?
@
sdebruyn commentedon May 20, 2026
macOS
thegoodwinner commentedon May 21, 2026
Corroborating report - same 1.7.1 token-auth regression on Windows and Linux
Same 1.7.1 regression as #594, reproduced on two more platforms. With macOS (#594) + Windows + Linux all affected, this is clearly not platform-specific.
Posting here rather than opening a new issue since the trigger is identical (
SQL_COPT_SS_ACCESS_TOKENviaattrs_before, 1.7.1 only) - happy to split if you'd prefer.Details
attrs_before={1256: token_struct}.Symptom
Unlike #594's SIGBUS on macOS arm64, on Windows and Linux the driver does not crash - it raises Python exceptions, but
connect()fails. Two error signatures, both fromddbc_bindings.Connection:Verbatim from Azure Functions on Linux (production, 2026-05-20 13:04:49 UTC, mssql-python 1.7.1):
The token is valid - A/B against pyodbc with the same token bytes
I acquire one access token, pack it once into the standard SQL Server token struct, and feed the identical bytes to both drivers in a loop:
Same token struct, same server, same machine, same moment: pyodbc 8/8, mssql-python 1.7.1 0/8. Note
0x2746is normally a transient network fault - but pyodbc, fed the identical token at the same instant, got zero of them. So under 1.7.1 this is not a transient; the access-token connect path is broken. The token and the database grant are demonstrably fine. Consistent with #594, this works on 1.6.0; only 1.7.1 fails.Reproduce
saurabh500 commentedon May 21, 2026
I could repro both the scenarios. Working on the fix
Use per-attribute owned buffers for deferred connect attributes
Document ICR / pool-reset lifetime requirements for deferred attribut…
FIX: Store deferred connect-attribute values in member buffers (#594) (…
RELEASE: 1.8.0 (#605)