Skip to content

Deprecate TransparentNetworkIPResolution and switch MultiSubnetFailover on by default #4494

Open
1 of 1 issue completed

Description

@dlevy-msft-sql

Is your feature request related to a problem? Please describe.

TransparentNetworkIPResolution (TNIR) has become the more error‑prone of two overlapping "connect faster across multiple DNS-resolved IPs" strategies in Microsoft.Data.SqlClient, and it is on by default only on .NET Framework:

Even on .NET Framework, the code path silently disables TNIR whenever it is likely to hurt the caller — Azure SQL endpoints, any Microsoft Entra ID auth method, or AccessToken (see ShouldDisableTnir). That signal alone is worth acting on: the driver already believes TNIR is the wrong default for the majority of modern workloads, but leaves it on for everyone else.

Related history:

MultiSubnetFailover (MSF) covers the same "connect faster across multiple target IPs" goal, works consistently on both .NET Framework and modern .NET, applies to any listener that resolves to more than one IP (despite the name, the IPs do not have to live in different subnets), is the documented strategy for SQL Server Always On availability group listeners, and already has an opt‑in default switch: Switch.Microsoft.Data.SqlClient.EnableMultiSubnetFailoverByDefault (see LocalAppContextSwitches).

Describe the solution you'd like

In a future major version:

  1. Mark TNIR obsolete on the public API surface

    • [Obsolete("...")] on:
      • SqlConnectionStringBuilder.TransparentNetworkIPResolution (both netcore/ref and netfx/ref reference assemblies).
      • The "Transparent Network IP Resolution" / "TransparentNetworkIPResolution" connection‑string keyword documentation on SqlConnection.ConnectionString.
    • Obsoletion message should point at MultiSubnetFailover as the recommended alternative and note that TNIR is .NET Framework–only.
  2. Flip the .NET Framework default for TNIR to false

    • Effectively invert Switch.Microsoft.Data.SqlClient.DisableTNIRByDefaultInConnectionString so DisableTnirByDefault returns true by default.
    • Provide a compatibility switch (Switch.Microsoft.Data.SqlClient.UseLegacyTnirDefault or equivalent) so callers that still depend on TNIR‑on can opt back in for one release cycle.
  3. Flip the default for MultiSubnetFailover to true

    • Effectively invert Switch.Microsoft.Data.SqlClient.EnableMultiSubnetFailoverByDefault so MultiSubnetFailover returns true by default on both .NET Framework and modern .NET.
    • Provide a compatibility switch to restore the historic false default for one release cycle.
  4. Documentation and migration guide

    • Update the connection string keyword tables (SqlConnection.xml, SqlConnectionStringBuilder.xml) to describe the new defaults and the obsolete status of TNIR.
    • Publish a short migration note covering the two compatibility switches and the behavior differences observed by apps that previously relied on TNIR.

Describe alternatives you've considered

  • Leave the current auto‑disable logic in place and do nothing else. Preserves back‑compat, but keeps the API surface confusing, keeps a keyword that throws on modern .NET, and forces docs to keep explaining a workflow that is silently disabled for most callers.
  • Remove TNIR entirely from .NET Framework. Simpler long-term, but this is a breaking change with no runway. Marking obsolete and flipping the default is the standard staged deprecation.
  • Only flip TNIR default, do not change MSF default. Fixes the "silent misconfiguration" side, but leaves callers whose listener resolves to multiple target IPs (including availability group listeners) with no default retry strategy — worse than status quo for that population.

Additional context

  • Public API changes should be gated through the reference assemblies (netcore/ref, netfx/ref) and reviewed against policy/coding-best-practices.md and .github/instructions/api-design.instructions.md.
  • Existing compatibility switch precedents: UseLegacyFailoverAlternationOnLoginSqlErrors, DisableTNIRByDefaultInConnectionString, EnableMultiSubnetFailoverByDefault — this proposal follows the same shape.
  • Impact on LoginNoFailover / LoginWithFailover should be modest: TNIR paths already short‑circuit via disableTnir; MSF paths are the ones the code exercises for Azure SQL and multi‑target‑IP listener scenarios today.
  • Related recent PR (docs correction, not a behavior change): docs: correct TransparentNetworkIPResolution behavior wording (Fixes #4489) #4493.

Activity

  1. github-actions commented on Jul 30, 2026

    @github-actions

    🔍 Triage Summary

    Check Result
    Issue type Feature
    Environment N/A — feature request, no environment details required
    Area Area\Managed SNI / Area\Netfx (connection string keyword behavior spans both layers; primary impact is .NET Framework TNIR default and the cross-platform MSF default)
    Duplicates Potentially related: #3574 (TNIR auto-disable for Azure SQL/Entra), #4489 (TNIR docs gap, fixed by #4493), #99 (historical KeywordNotSupported on modern .NET)
    Regression Not indicated — this is a forward-looking deprecation proposal

    Analysis

    This feature request proposes a staged, three-part deprecation of TransparentNetworkIPResolution (TNIR) and a simultaneous flip of the MultiSubnetFailover default to true. The proposal is well-scoped and follows established patterns in this codebase (AppContext compatibility switches, [Obsolete] annotations on reference assemblies). The affected surface spans SqlConnectionStringBuilder, DbConnectionStringDefaults, LocalAppContextSwitches, and the XML doc snippets in doc/snippets/. Because these are default-changing breaking changes, they are appropriately deferred to a future major version and require a migration guide. Severity is P2 — meaningful developer-experience improvement with a clear rollback path, but no current correctness failure.

    Next Steps

    1. Track against next major version milestone. The three sub-items (TNIR [Obsolete], TNIR default flip, MSF default flip) can be filed as individual child tasks under this epic.
    2. Assign to Copilot coding agent to implement. Suggested investigation scope:
      • Add [Obsolete] to SqlConnectionStringBuilder.TransparentNetworkIPResolution in both netcore/ref/Microsoft.Data.SqlClient.cs and netfx/ref/Microsoft.Data.SqlClient.cs.
      • Invert the DisableTnirByDefault property in LocalAppContextSwitches.cs (default true) and add a legacy opt-in switch Switch.Microsoft.Data.SqlClient.UseLegacyTnirDefault.
      • Invert the MultiSubnetFailoverByDefault property in LocalAppContextSwitches.cs (default true) and add a legacy opt-out switch.
      • Update doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml and SqlConnectionStringBuilder.xml with new defaults and obsolete notices.
      • Add or update unit tests in LocalAppContextSwitchesTest.cs and functional tests covering the new defaults.
    3. Review docs: correct TransparentNetworkIPResolution behavior wording (Fixes #4489) #4493 (merged docs correction) to ensure the migration guide does not contradict it.

    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 issue #4494 · 30.5 AIC · ⌖ 9.17 AIC · ⊞ 8.6K · ◷

  2. moved this from To triage to In progress in SqlClient Boardon Jul 30, 2026
  3. added this to the 7.1.0-preview3 milestone on Jul 30, 2026
  4. cheenamalhotra commented on Sep 2, 2026

    @cheenamalhotra
    Member

    PR #4576 is now merged, TNIR is now deprecated. New defaults will come into effect in the next major release.

  5. linked a pull request that will close this issueDeprecate TransparentNetworkIPResolution #4576on Oct 6, 2026
  6. modified the milestones: 8.0.0, 8.0.0-preview1 on Oct 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

ApprovedUse for Features approved for implementation.

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions