Visitar URL original
Enable MultiSubnetFailover by default and disable Framework TNIR by cheenamalhotra · Pull Request #4927 · dotnet/SqlClient · GitHub
Skip to content

Enable MultiSubnetFailover by default and disable Framework TNIR - #4927

Merged
cheenamalhotra merged 13 commits into
mainfrom
dev/cheena/multisubnet-failover-default
Nov 2, 2026
Merged

cheenamalhotra merged 13 commits into
mainfrom
dev/cheena/multisubnet-failover-default

Conversation

@cheenamalhotra

@cheenamalhotra cheenamalhotra commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

Description

Turns on MultiSubnetFailover (MSF) by default and turns off TNIR by default on .NET Framework. No public API signature changes. Builds on #4929 (merged).

Intentional behavior changes

MSF default (.NET and .NET Framework)

  • When MultiSubnetFailover is not set, it is true for TCP connections. The client tries all resolved IPs in parallel.
  • An explicit value is always used as-is.
  • The default applies only when the resolved protocol is TCP: tcp:, a TCP alias or Network Library, or no prefix (managed SNI, or a remote host on native SNI).
  • The default is off for:
    • Named Pipes and Shared Memory: np:, lpc:, pipe paths, and non-TCP aliases or Network Library.
    • LocalDB, admin:, and via:.
    • A local server with no prefix on native SNI (., (local), localhost, machine name), so Shared Memory/NP still work.
    • A configured Failover Partner or a partner sent by the server (database mirroring).
  • With native SNI on Windows, a remote host with no prefix now uses TCP only. The fallback to Named Pipes is gone. Use np: or MultiSubnetFailover=false to keep it.
  • With MSF on, IPAddressPreference and TNIR are ignored, as before.
  • SqlConnectionStringBuilder.MultiSubnetFailover returns the default (true), not the value used for the connection.

TNIR default (.NET Framework)

  • TransparentNetworkIPResolution defaults to false. An explicit value is used as-is.

Unchanged

  • An explicit MultiSubnetFailover=true still throws for non-TCP protocols and for a failover partner.
  • MSF still fails when a host resolves to more than 64 IPs.

Compatibility switches (both already exist on main)

  • Switch.Microsoft.Data.SqlClient.EnableMultiSubnetFailoverByDefault=false restores the old MSF default.
  • Switch.Microsoft.Data.SqlClient.DisableTNIRByDefaultInConnectionString=false restores the old TNIR default.

Docs: doc/networking-defaults.md, plus the SqlConnection and SqlConnectionStringBuilder remarks.

Known gaps: Windows native SNI and .NET Framework runtime coverage needs CI. Parallel connect failing when one address errors early was fixed in #4929 (merged).

  • Tests added or updated
  • Public API changes documented (defaults and migration; no signature changes)
  • Verified against customer repro (no customer repro supplied)
  • Ensure no breaking changes introduced (intentional default changes, documented above)

Issues

Fixes #4876. Related: #4494, #4928.

Testing

Unit tests, net10.0 on macOS: 142 passed, 1 failed. The failure is IntegratedAuthConnectionTest, a Windows SSPI test that fails on macOS without this change too.

dotnet test src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj -f net10.0 --filter "FullyQualifiedName~SqlConnectionOptionsTest|FullyQualifiedName~SimulatedServerTests.ConnectionTests|FullyQualifiedName~SqlConnectionStringBuilderTest|FullyQualifiedName~LocalAppContextSwitchesTest"
  • ConnectionFailoverTests was not run locally. Its failover-partner tests hang on macOS, and one also hangs without this change. They need Windows CI.
  • Driver builds for net10.0 and net462 (-p:TargetOs=Windows_NT). Manual tests build for net10.0.
  • Manual tests updated: TcpDefaultForAzureTest expects TCP with MSF on. ConfigurableIpPreferenceTest sets MultiSubnetFailover=false.
  • SQL-backed manual tests and Windows native SNI tests were not run locally.

Guidelines

Please review the contribution guidelines before submitting a pull request:

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Comment thread doc/networking-defaults.md Resolved
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new default exposes unresolved connection-failure, socket-cleanup, and pre-login timeout defects.

3 open issues
What changed in this PR

This PR changes SqlClient’s networking defaults for a major release: MultiSubnetFailover becomes enabled on both runtimes, while .NET Framework’s TransparentNetworkIPResolution becomes disabled.

Changes:

  • Retains existing compatibility switches and explicit connection-string overrides.
  • Adds default/reset and synchronous/asynchronous connection coverage, and updates mirroring tests to opt out.
  • Documents migration requirements and incompatible connection scenarios without changing public API signatures.
File Description
src/​Microsoft.Data.SqlClient/​tests/​UnitTests/​SimulatedServerTests/​ConnectionTests.cs Adds default and compatibility-switch connection tests.
src/​Microsoft.Data.SqlClient/​tests/​UnitTests/​SimulatedServerTests/​ConnectionFailoverTests.cs Explicitly disables MSF in existing failover scenarios.
src/​Microsoft.Data.SqlClient/​tests/​UnitTests/​Microsoft/​Data/​SqlClient/​SqlConnectionOptionsTest.cs Tests defaults, overrides, resets, and mirroring compatibility.
src/​Microsoft.Data.SqlClient/​tests/​UnitTests/​Microsoft/​Data/​SqlClient/​LocalAppContextSwitchesTest.cs Updates expected switch defaults.
src/​Microsoft.Data.SqlClient/​tests/​ManualTests/​SQL/​MirroringTest/​ConnectionOnMirroringTest.cs Disables MSF for mirroring connections.
src/​Microsoft.Data.SqlClient/​tests/​ManualTests/​SQL/​ConnectivityTests/​ConnectionBehaviorTest.cs Adds sync/async SQL Server connection coverage.
src/​Microsoft.Data.SqlClient/​tests/​FunctionalTests/​SqlConnectionStringBuilderTest.cs Adds MSF opt-outs to mirroring inputs.
src/​Microsoft.Data.SqlClient/​src/​Microsoft/​Data/​SqlClient/​LocalAppContextSwitches.cs Changes both networking switch defaults and their documentation.
README.md Links the migration guide.
doc/​snippets/​Microsoft.Data.SqlClient/​SqlConnectionStringBuilder.xml Documents property defaults and compatibility options.
doc/​snippets/​Microsoft.Data.SqlClient/​SqlConnection.xml Updates connection-string defaults and restrictions.
doc/​networking-defaults.md Explains migration and restoring previous behavior.
.github/​instructions/​features.instructions.md Updates the feature and switch reference tables.

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 27, 2026 17:14
cheenamalhotra and others added 2 commits October 27, 2026 10:17
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…t-failover-default

# Conflicts:
#	src/Microsoft.Data.SqlClient/tests/UnitTests/SimulatedServerTests/ConnectionTests.cs
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The default-on networking change lacks Windows native SNI and .NET Framework runtime validation, requiring maintainer checks of synchronous, asynchronous, and compatibility-switch behavior before approval.

3 open issues
1 previously missed issue

In code that hasn't changed since last review

Medium severity Add MSF=false to Named Pipes test connection strings

src/​Microsoft.Data.SqlClient/​src/​Microsoft/​Data/​SqlClient/​LocalAppContextSwitches.cs:424

SqlNamedPipesTest.ValidConnStringTest opens DataTestUtility.NPConnectionString without an MSF opt-out, and config.default.jsonc:10 still supplies a Named Pipes string without one. With the new default, Windows managed-SNI runs reject that connection with SNI_ERROR_49 before opening the pipe, so this success test fails even with a healthy server. Add MultiSubnetFailover=false to the shared Named Pipes test inputs while preserving default-on coverage for TCP.

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 27, 2026 17:20
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Removing MultiSubnetFailover=false causes the test to fail for valid mirroring configurations that the current setup check does not exclude, requiring a nonmirrored target or mirroring-aware skip condition.

1 open issue
3 resolved since last review

Review effort: Balanced

…ubnet-failover-default

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 27, 2026 20:38
@cheenamalhotra
cheenamalhotra changed the base branch from main to dev/cheena/parallel-connect-fix October 27, 2026 20:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Missing Windows native-SNI, .NET Framework, and SQL-backed runtime validation, together with unresolved mirroring and non-TCP compatibility, require human review of this connection-default change’s rollout risk.

1 open issue

Review effort: Balanced

@paulmedynski paulmedynski left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes for the confirmed test failures caused by enabling MultiSubnetFailover by default. The affected tests still assume the previous networking defaults.

  1. Named Pipes and LocalDB tests need an explicit MSF opt-out.
    CI reports ArgumentException: “Connecting to a SQL Server instance using the MultiSubnetFailover connection option is only supported when using the TCP protocol.”

    This affects LocalDB, Named Pipes MARS/cancellation, streaming, retry, and named-instance scenarios. Set MultiSubnetFailover=false in the relevant non-TCP test connection strings and fixtures so these tests continue exercising their intended behavior. Tests specifically validating the incompatible combination should retain MSF and assert rejection.

  2. IP-address preference tests must disable MSF.
    ConfigurableIpPreferenceTest.ConfigurableIpPreference fails Assert.NotNull() because the new default selects parallel connection logic rather than the IPAddressPreference-controlled path.

    Set MultiSubnetFailover=false for these preference tests; disabling TNIR alone is insufficient.

  3. Default-protocol expectations need updating.
    TcpDefaultForAzureTest.NonAzureNoProtocolConnectionTestWindows expects Named Pipes Provider but now receives a TCP failure.

    Update the expectation for MSF-enabled defaults, or explicitly disable MSF if the test is intended to preserve coverage of legacy protocol fallback.

@cheenamalhotra

Copy link
Copy Markdown
Member Author

@paulmedynski thanks, addressed:

  1. Named Pipes / LocalDB: fixed in the driver (642f7ed). When MSF is not set, the default now applies only to TCP. It is off for Named Pipes, Shared Memory, LocalDB, non-TCP aliases, native SNI local servers without a prefix, and failover partners. Explicit MultiSubnetFailover=true still throws for non-TCP, as before. So these tests need no opt-out.
  2. IP preference: ConfigurableIpPreferenceTest now sets MultiSubnetFailover=false (50a0df1).
  3. Default protocol: TcpDefaultForAzureTest now expects TCP when MSF is on.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Hostname detection incorrectly treats remote hosts sharing the client’s short name as local, disabling the new MultiSubnetFailover default and parallel connection attempts for unprefixed native SNI connections.

1 open issue
1 resolved since last review

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 29, 2026 20:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The local-host check accepts unrelated remote hosts sharing the machine’s short name, causing native SNI to disable parallel TCP dialing and permit Named Pipes fallback for remote connections.

1 open issue

Review effort: Balanced

benrr101
benrr101 previously approved these changes Oct 29, 2026

@benrr101 benrr101 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly approved. Small request regarding auto-properties

Base automatically changed from dev/cheena/parallel-connect-fix to main October 30, 2026 03:59
@cheenamalhotra
cheenamalhotra dismissed benrr101’s stale review October 30, 2026 03:59

The base branch was changed.

cheenamalhotra and others added 2 commits October 29, 2026 21:01
- Treat only the exact machine name or local FQDN as local, not any host
  sharing the short name.
- Make MultiSubnetFailover an auto-property and drop the redundant call in
  LoginWithFailover.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 30, 2026 04:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Default MSF remains enabled for cached mirroring partners, breaking non-TCP pool expansion, while the cached-IP preference test lacks an opt-out and has timing-dependent assertions.

2 open issues
1 resolved since last review

Review effort: Balanced

.NET Framework requires it when the server sends a partner.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 30, 2026 04:30
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The default connection changes span managed/native SNI and .NET Framework, while CI and Windows/SQL-backed runtime validation remain pending.

No open issues 🎉

2 resolved since last review

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 30, 2026 04:35
@cheenamalhotra cheenamalhotra moved this from Waiting for customer to In review in SqlClient Board Oct 30, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The default-on transport change still lacks Windows native-SNI, .NET Framework, and SQL-backed runtime validation, while current-head CI remains pending.

No open issues 🎉

Review effort: Balanced

@codecov

codecov Bot commented Oct 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.83721% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 66.30%. Comparing base (5d17a35) to head (cadb80d).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...Data/SqlClient/Connection/SqlConnectionInternal.cs 95.65% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4927      +/-   ##
==========================================
- Coverage   67.74%   66.30%   -1.45%     
==========================================
  Files         311      305       -6     
  Lines       45270    68381   +23111     
==========================================
+ Hits        30668    45339   +14671     
- Misses      14602    23042    +8440     
Flag Coverage Δ
CI-SqlClient ?
PR-SqlClient-Project 66.30% <98.83%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cheenamalhotra
cheenamalhotra merged commit c1e89ab into main Nov 2, 2026
123 checks passed
@cheenamalhotra
cheenamalhotra deleted the dev/cheena/multisubnet-failover-default branch November 2, 2026 18:47
@github-project-automation github-project-automation Bot moved this from In review to Done in SqlClient Board Nov 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Switch MultiSubnetFailover on by default

5 participants