Skip to content

[SQL Server 2005] System.Data.SqlClient: pre-login fails with SSL error even with Encryption=false #24

Description

@kostix

Platform : Debian 8 "Jessie"
Runtime : 1.0.0-preview1-002702,coreclr,x64,linux
System.Data.SqlClient : 4.1.0-rc2-24027

ConnectionString : Server=tcp:server.domain.lan,1433;User ID=XXXX;Password=XXXX;Encrypt=False"

An attempt to connect to a Microsoft SQL Server 2005 instance results in the following exception:

Project foo (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
Unhandled Exception: System.Data.SqlClient.SqlException: A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: SSL Provider, error: 31 - Encryption(ssl/tls) handshake failed) ---> System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: size
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at System.Data.SqlClient.SNI.SslOverTdsStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.Stream.<>c.<BeginReadInternal>b__39_0(Object <arg>)
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Threading.Tasks.TaskToApm.End[TResult](IAsyncResult asyncResult)
   at System.Net.FixedSizeReader.ReadCallback(IAsyncResult transportResult)
--- End of stack trace from previous location where exception was thrown ---
   at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Data.SqlClient.SNI.SNITCPHandle.EnableSsl(UInt32 options)
   at System.Data.SqlClient.SNI.SNIProxy.EnableSsl(SNIHandle handle, UInt32 options)
   --- End of inner exception stack trace ---
   at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, Boolean applyTransientFaultHandling)
   at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.Open()
   at ConsoleApplication.Program.Main(String[] args)

To me, the error looks as if the Encrypt=false just does not get communicated properly in the PRELOGIN packet because the exception is the same no matter if I set Encrypt to true (the default) or false.

Adding TrustServerCertificate=true with the Encrypt setting enabled or disabled has no effect.

The Encrypt setting is parsed as if I specify an invalid value for it, I get an error about it.

Activity

  1. kostix commented on May 18, 2016

    @kostix
    Author

    I'd say the second line in the exception stack trace, System.Data.SqlClient.SNI.SslOverTdsStream.Read(... looks especially suspicious: it suggests SSL reader is used even though we told the client to not use it.

  2. kostix commented on May 18, 2016

    @kostix
    Author

    Here's the capture file created by tcpdump of a sample session under Encrypt=false.

    The interesting thing is that the client is sending its PRELOGIN packet twice, and MS-TDS dissector in Wireshark considers the server's response to the first PRELOGIN packet as invalid.

  3. saurabh500 commented on May 18, 2016

    @saurabh500
    Collaborator
  4. kostix commented on May 18, 2016

    @kostix
    Author

    In the meantime I have converted the capture to a Network Monitor v2 format using the editcap utility and inspected the generated capture in the Microsoft Network Monitor 3.4 (which has much better dissector for MS-TDS).

    Inspecting the capture in NM, I see:

    • The dissector fails to properly parse the initial PRELOGIN packet we sent. Specifically it fails to parse the encryption option's data.
    • The server's response packet explicitly has encryption option set to "off".
    • Still, the second PRELOGIN packet we sent appears to contain the TLS 1.2 handshake, and the server apparently disconnects us after receiving it (supposedly failing to parse what should not have been a TLS handshake as "plain" payload).

    Hence if we assume the NM's dissector is correct, its output might actually indicate several problems:

    • We might be generating our PRELOGIN packet incorrectly.
    • We fail to deal with the server telling us not to use encryption.
    • The exception raised appears to be misleading as we did not actually read anything from the server after it disconnected us.

    Here's that capture file.

  5. saurabh500 commented on May 18, 2016

    @saurabh500
    Collaborator

    @kostix Does this connectivity work from Windows using the same app?

  6. kostix commented on May 18, 2016

    @kostix
    Author

    Yes. Verified using dotnet restore + dotnet run on a Windows 7 SP1 x64 using standalone SDK.

    Here are archived lockfiles from both projects (that one whose name starts with "win7" is from the Windows build, which works).

  7. saurabh500 commented on May 18, 2016

    @saurabh500
    Collaborator

    Yes. Verified using dotnet restore + dotnet run on a Windows 7 SP1 x64 using standalone SDK.

    Is the Yes is for successful connection from Windows ?
    We are looking into this.

  8. kostix commented on May 18, 2016

    @kostix
    Author

    Yes, the connection works.

    From the dump taken on that host using NM, it appears that the TLS session is still being used while authenticating, just it manages to happen OK on Windows.

    Here's the screenshot.

    There, the 192.168.2.145 is the client and .25 is the server.
    Highlighted, is the server's PRELOGIN response packet indicating encryption turned off.
    As you can see, what follows is the TLS-protected exchange.

  9. joshfree commented on Jun 2, 2016

    @joshfree
    Member

    @saurabh500 @corivera any update on this? Are you planning to have a fix ready to review today or tomorrow?

  10. corivera commented on Jun 2, 2016

    @corivera
    Member

    @joshfree Currently trying to diagnose the problem.

  11. corivera commented on Jun 2, 2016

    @corivera
    Member

    @kostix Do you get this error on any other Linux distro, or is it limited to just Debian? If you haven't tested this, that's fine; just wondering. I'm actually getting generic TCP timeouts when connecting to SQL 2005 from Ubuntu (which is still unexpected).

  12. kostix commented on Jun 2, 2016

    @kostix
    Author
  13. 6 remaining items

  14. paalmoest commented on Nov 16, 2016

    @paalmoest

    Will the fix for this issue be present in core 1.1 ? @saurabh500

  15. removed their assignment
    on Apr 24, 2017
  16. markmcdowell commented on May 11, 2017

    @markmcdowell

    I've just hit this on centos 7. Any workarounds?

  17. sakopov commented on Sep 28, 2017

    @sakopov

    Any progress?

  18. sshinault commented on Mar 19, 2018

    @sshinault

    I am having the same problem connecting from an Amazon Linux AMI EC2 host to a Sql Server 2005 instance. I am using the mssql-cli client to test why my AWS Lamdba functions (C# .NET Core) were getting connection timeouts.

    The packet captures look almost exactly the same as the original poster's - 2nd PRELOGIN request appears to attempt to send TLS/SSL payload and server responds by closing connection.

    mssql-cli login attempts from Windows 10 host to this server succeed. SQL Server has encryption turned OFF.

  19. brokenthorn commented on Apr 18, 2018

    @brokenthorn

    I have never had this problem and have never upgraded SQL Operations Studio yet the same saved connections I have been using before now suddenly don't work anymore. I'm on macOS High Sierra.

  20. LandonCampbell commented on May 5, 2018

    @LandonCampbell

    @sshinault Did you ever find a solution? I'm getting this from C# AWS lamba functions too.

  21. sshinault commented on May 7, 2018

    @sshinault

    @LandonCampbell No, we decided to upgrade to SQL Server 2008 R2 which works fine.

  22. LandonCampbell commented on May 7, 2018

    @LandonCampbell

    @sshinault Thanks, I appreciate the feedback.

  23. divega commented on May 15, 2019

    @divega

    As recently announced in the .NET Blog, focus on new SqlClient features an improvements is moving to the new Microsoft.Data.SqlClient package. For this reason, we are moving this issue to the new repo at https://github.com/dotnet/SqlClient. We will still use https://github.com/dotnet/corefx to track issues on other providers like System.Data.Odbc and System.Data.OleDB, and general ADO.NET and .NET data access issues.

  24. transferred this issue fromdotnet/corefxon May 15, 2019
  25. David-Engel commented on May 20, 2019

    @David-Engel
    Contributor

    Assuming all above issues are related to SQL Server 2005 and not a currently supported SQL version and closing this issue. Feel free to re-open if it is present against a currently supported version.

  26. added a commit that references this issue on Jun 25, 2026
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

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions