Repository navigation
Improve the timeout error when closing an incompletely consumed SqlDataReader #4639
Description
Activity
- addedArea\Managed SNIIssues that are targeted to the Managed SNI codebase.Issues that are targeted to the Managed SNI codebase.
on Sep 3, 2026 - added a parent issue
on Sep 3, 2026 /triage
🔍 Triage Summary (on-demand re-triage)
Check Result Issue type Bug Environment All required environment details provided for investigation Area Area\Managed SNIDuplicates Potentially related: #4638, #1530 (parent issue) Regression Not indicated — reproduced consistently across Microsoft.Data.SqlClient 5.1.5 through 7.1.0-preview2 Analysis
This issue asks for an improved, more actionable error message when
SqlDataReader.Close()/CloseAsync()times out while draining an incompletely consumed result set on Linux (Managed SNI path), rather than surfacing an opaqueWin32Exception (258): Unknown error 258. It is a documentation/diagnostics improvement on top of already-understood behavior (Cause B from #1530), not a new functional defect, so it is best classified as a P2 usability/diagnostics enhancement. The fix would likely live inSqlDataReader.Close/CloseAsyncand the TDS parser's row-draining path, where the timeout exception is caught/wrapped before being rethrown.Next Steps
- Recommend reviewing Preserve the original exception when SqlDataReader teardown also times out #4638 ("Preserve the original exception when SqlDataReader teardown also times out") and parent Intermittent Unknown error 258 with no obvious cause #1530 together with this issue, since all three describe related aspects of the same close/drain timeout behavior — a combined fix may be more efficient than three separate PRs.
- Assign this issue to the Copilot coding agent to investigate
SqlDataReader.Close/CloseAsyncinsrc/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/and wrap the timeoutSqlException/Win32Exceptionraised during drain with additional context (e.g. a message noting the timeout occurred while closing an incompletely consumed reader, with guidance to consume the result set or cancel the command first), while preserving the original exception as inner exception per Preserve the original exception when SqlDataReader teardown also times out #4638's ask. - Ensure any fix adds unit/manual tests covering both
Close()andCloseAsync()paths on the Managed SNI code path, per repository testing guidelines (cover sync and async variants).
Note: This triage summary is auto-generated by an AI agent. The analysis and suggestions above have not been verified by a human maintainer. Please treat as preliminary guidance only.
Generated by SqlClient Issue Auto-Triage for #4639 · copilot · auto · 66.8 AIC · ⌖ 13.1 AIC · ⊞ 11.9K · ◷
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsBacklog
Describe the bug
Closing a
SqlDataReaderbefore consuming the full result set drains the remaining rows while the command timeout is still armed. If the drain exceeds the timeout on Linux, the caller receives an opaque timeout ending inWin32Exception (258): Unknown error 258.The behavior is expected, but the error does not explain that the timeout occurred while draining an incompletely consumed result set or suggest canceling the command before closing the reader.
This is Cause B from #1530. See the deterministic analysis and version matrix and the request to track an improved error separately.
To reproduce
CommandTimeout.SqlDataReader.Close()orCloseAsync()without first canceling the command.Unknown error 258.The linked analysis includes results across Microsoft.Data.SqlClient 5.1.5 through 7.1.0-preview2.
Expected behavior
Surface an error that identifies the timeout as occurring while closing and draining an incompletely consumed reader, with guidance to consume the result set or cancel the command before closing it.
Further technical details
Microsoft.Data.SqlClient version: Reproduced from 5.1.5 through 7.1.0-preview2
.NET target: net8.0 and net9.0 assets, tested on .NET 8, .NET 9, and .NET 10
SQL Server version: Reproduced with SQL Server in Docker
Operating system: Linux
Additional context
Explicit
Close()andCloseAsync()surface the exception.Dispose()currently swallows theSqlExceptionfromClose(). EF Core calls the throwing close paths, while Dapper cancels the command during teardown and avoids this result.