Skip to content

Docs: SqlConnection.ConnectionString TransparentNetworkIPResolution row misrepresents actual behavior #4489

Closed

Description

@dlevy-msft-sql

Summary

The TransparentNetworkIPResolution row in the SqlConnection.ConnectionString keyword table (rendered on learn.microsoft.com) has three concrete inaccuracies compared to the current netfx behavior in SqlConnectionInternal.ShouldDisableTnir. The source lives in doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml. The same wording is echoed on the TransparentNetworkIPResolution property doc in SqlConnectionStringBuilder.xml.

Current text (excerpted)

Transparent Network IP Resolution ... When the value of this key is set to true, the application is required to retrieve all IP addresses for a particular DNS entry and attempt to connect with the first one in the list. If the connection is not established within 0.5 seconds, the application will try to connect to all others in parallel. When the first answers, the application will establish the connection with the respondent IP address.

If the MultiSubnetFailover key is set to true, TransparentNetworkIPResolution is ignored.

If the Failover Partner key is set, TransparentNetworkIPResolution is ignored.

... If the Authentication key is set to Active Directory Password or Active Directory Integrated, TransparentNetworkIPResolution is ignored.

Bugs

1. 0.5 seconds is not the total TNIR timeout

0.5 seconds maps to ADP.MinimumTimeoutForTnirMs = 500 in AdapterUtil.cs, which is applied only to the first TNIR attempt when the calculated unit interval is smaller than 500 ms:

// SqlConnectionInternal.LoginNoFailover (netfx)
if (isFirstTransparentAttempt)
{
    nextTimeoutInterval = Math.Max(ADP.MinimumTimeoutForTnirMs, nextTimeoutInterval);
}

The TNIR time budget is a sequence of per-attempt timers whose durations are failoverTimeoutStep * timeout.MillisecondsRemaining with a 1, 2, 4 multiplier pattern (using ADP.FailoverTimeoutStepForTnir), governed by the overall Connect Timeout. It's not "connect within 0.5 seconds; otherwise switch to parallel to all IPs".

Suggested wording:

The first TNIR attempt is given a minimum of 500 ms; each subsequent attempt receives a longer share of the remaining Connect Timeout budget until the overall Connect Timeout is reached.

2. Authentication list is incomplete

The doc says TransparentNetworkIPResolution is ignored only for Active Directory Password and Active Directory Integrated. The actual implementation in SqlConnectionInternal.ShouldDisableTnir treats every currently supported Microsoft Entra ID method plus the access-token-in-bytes path as a trigger:

bool isFedAuthEnabled = _accessTokenInBytes != null ||
    connectionOptions.Authentication == SqlAuthenticationMethod.ActiveDirectoryPassword ||
    connectionOptions.Authentication == SqlAuthenticationMethod.ActiveDirectoryIntegrated ||
    connectionOptions.Authentication == SqlAuthenticationMethod.ActiveDirectoryInteractive ||
    connectionOptions.Authentication == SqlAuthenticationMethod.ActiveDirectoryServicePrincipal ||
    connectionOptions.Authentication == SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow ||
    connectionOptions.Authentication == SqlAuthenticationMethod.ActiveDirectoryManagedIdentity ||
    connectionOptions.Authentication == SqlAuthenticationMethod.ActiveDirectoryMSI ||
    connectionOptions.Authentication == SqlAuthenticationMethod.ActiveDirectoryDefault ||
    connectionOptions.Authentication == SqlAuthenticationMethod.ActiveDirectoryWorkloadIdentity;

Suggested wording:

If the Authentication key uses any Microsoft Entra ID method (Active Directory Password, Integrated, Interactive, Service Principal, Device Code Flow, Managed Identity, MSI, Default, Workload Identity), or if AccessToken is set, TransparentNetworkIPResolution is ignored.

3. Missing the explicit-set escape hatch and the Azure endpoint override

ShouldDisableTnir returns true (disable TNIR) for Azure SQL endpoints and for federated auth only when TransparentNetworkIPResolution isn't in the connection string. When the key is present with any value, the explicit value wins and the automatic override is skipped:

bool isTnirExplicitlySpecifiedInConnectionOptions =
    connectionOptions.Parsetable.ContainsKey(DbConnectionStringKeywords.TransparentNetworkIpResolution);
return isTnirExplicitlySpecifiedInConnectionOptions
    ? false
    : (isAzureEndPoint || isFedAuthEnabled);

The current doc doesn't mention:

  • The automatic Azure SQL endpoint override (based on ADP.IsAzureSqlServerEndpoint).
  • The fact that any explicit TransparentNetworkIPResolution value bypasses both the Azure and federated-auth override.

This gap matters in practice: apps on .NET Framework that set TransparentNetworkIPResolution=True explicitly against Azure SQL end up in a per-attempt retry loop against the routed endpoint until the overall Connect Timeout is reached, instead of returning to the Azure SQL gateway between attempts.

Suggested wording:

On .NET Framework, if TransparentNetworkIPResolution isn't specified in the connection string, the driver automatically disables TNIR when the data source is an Azure SQL endpoint or when Authentication uses a Microsoft Entra ID method. An explicit TransparentNetworkIPResolution=True in the connection string overrides this automatic behavior; to restore it, remove the keyword from the connection string or set it to False. On .NET (non-Framework), TransparentNetworkIPResolution has no effect.

Also affected

Same wording appears on the SqlConnectionStringBuilder.TransparentNetworkIPResolution property doc in SqlConnectionStringBuilder.xml. Consider updating both files together.

Verification

All quoted code is from dotnet/SqlClient/main at time of filing.

Activity

  1. github-actions commented on Jul 29, 2026

    @github-actions

    🔍 Triage Summary

    Check Result
    Issue type Task
    Environment All required environment details provided for investigation
    Area Area\Documentation
    Duplicates None found
    Regression Not indicated

    Analysis

    This issue reports three concrete documentation inaccuracies in doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml (and echoed in SqlConnectionStringBuilder.xml) regarding the TransparentNetworkIPResolution keyword: (1) the "0.5 seconds then parallel" description misrepresents the actual per-attempt timeout budget logic; (2) the list of Entra ID authentication modes that disable TNIR is incomplete (missing Interactive, Service Principal, Device Code Flow, Managed Identity, MSI, Default, Workload Identity, and the access-token path); (3) the docs omit the important "explicit value wins" escape hatch and the Azure SQL endpoint automatic override. The reporter provides specific code references and suggested replacement wording, making this straightforward to fix. Severity: P3 (documentation correctness; no code behavior change needed).

    Next Steps

    • Update the TransparentNetworkIPResolution entry in doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml with the three suggested corrections (timeout wording, complete auth list, explicit-value/Azure-override note).
    • Apply the same corrections to doc/snippets/Microsoft.Data.SqlClient/SqlConnectionStringBuilder.xml.
    • Assign to Copilot coding agent to apply the documentation fixes using the exact suggested wording from the issue as a starting point.

    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 #4489 · 28.3 AIC · ⌖ 8.96 AIC · ⊞ 8.6K · ◷

  2. dlevy-msft-sql commented on Jul 29, 2026

    @dlevy-msft-sql
    ContributorAuthor

    Correction to Bug 3 suggested wording

    Verified today against dotnet/SqlClient/main: on .NET (non-Framework), TransparentNetworkIPResolution is not registered in s_keywordMap at all. Setting it in a connection string throws ArgumentException (KeywordNotSupported) when the driver parses the string, not "has no effect."

    Relevant guards in SqlConnectionOptions.cs:

    • Static-constructor call AddKeywordToMap(DbConnectionStringKeywords.TransparentNetworkIpResolution, ...) is inside #if NETFRAMEWORK.
    • Backing field _transparentNetworkIPResolution, the internal TransparentNetworkIPResolution property, and copy-constructor propagation are all #if NETFRAMEWORK.

    Runtime read site in TdsParserStateObject.ReadSniError:

    #if NETFRAMEWORK
    && (MultiSubnetFailover || TransparentNetworkIPResolution)
    #else
    && MultiSubnetFailover
    #endif

    Revised suggested wording for the closing sentence of Bug 3:

    On .NET (non-Framework), TransparentNetworkIPResolution isn't a recognized connection-string keyword. Setting it (with any value) throws ArgumentException (KeywordNotSupported) when the driver parses the connection string.

    This changes the customer-facing consequence: the current text ("has no effect") suggests TransparentNetworkIPResolution=False is a safe cross-target mitigation. It isn't. It breaks .NET (non-Framework) apps at parse time.

  3. moved this from To triage to In progress in SqlClient Boardon Jul 30, 2026
  4. added 2 commits that reference this issue on Jul 30, 2026
    6abfe58
    ec43fd6
  5. moved this from In progress to In review in SqlClient Boardon Jul 30, 2026
  6. moved this from In review to Done in SqlClient Boardon Aug 25, 2026
  7. added a commit that references this issue on Aug 25, 2026
    3473f48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions