Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ConnectionFailedException: The collection already contains item with same key 'net.transport' #1074

Closed
atiq-cs opened this issue Nov 7, 2021 · 5 comments
Assignees
Labels
Milestone

Comments

@atiq-cs
Copy link

atiq-cs commented Nov 7, 2021

Software versions
MySqlConnector version:
bug exists in nuget package versions starting with '2.0.0-beta.5'.
Specifically, 2.0.0-beta.5' and '2.0.0-rc.1' repro this.

Server type (MySQL, MariaDB, Aurora, etc.) and version:
MySQL

.NET version: .Net 6
ORM NuGet packages and versions: 2.0.0-beta.5 and 2.0.0-rc.1

Describe the bug
starting with version 2.0.0-beta.5 connection is failing with MySQL server. It was working till 1.4.0-beta.4. It still works if I downgrade to 1.4.0-beta.4.

Exception

Unhandled exception ConnectionFailedException: "The collection already contains item with same key 'net.transport''"
 ---> System.InvalidOperationException: "The collection already contains item with same key 'net.transport''"
   at System.Diagnostics.ActivityTagsCollection.Add(String key, Object value)
   at MySqlConnector.Core.ServerSession.OpenTcpSocketAsync(ConnectionSettings cs, ILoadBalancer loadBalancer, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 1059
   at MySqlConnector.Core.ServerSession.ConnectAsync(ConnectionSettings cs, MySqlConnection connection, Int32 startTickCount, ILoadBalancer loadBalancer, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 422
   at MySqlConnector.Core.ConnectionPool.ConnectSessionAsync(MySqlConnection connection, String logMessage, Int32 startTickCount, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ConnectionPool.cs:line 363
   at MySqlConnector.Core.ConnectionPool.GetSessionAsync(MySqlConnection connection, Int32 startTickCount, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ConnectionPool.cs:line 94
   at MySqlConnector.Core.ConnectionPool.GetSessionAsync(MySqlConnection connection, Int32 startTickCount, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ConnectionPool.cs:line 124
   at MySqlConnector.MySqlConnection.CreateSessionAsync(ConnectionPool pool, Int32 startTickCount, Nullable`1 ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlConnection.cs:line 911
   at MySqlConnector.MySqlConnection.OpenAsync(Nullable`1 ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlConnection.cs:line 405
   at Goodbye.WordPress.MysqlPostReader.ReadPostsAsync(CancellationToken cancellationToken)+MoveNext() in D:\Code\wordpress-export\Goodbye.WordPress\MysqlPostReader.cs:line 51
   --- End of inner exception stack trace ---
   at Goodbye.WordPress.MysqlPostReader.ReadPostsAsync(CancellationToken cancellationToken)+MoveNext() in D:\Code\wordpress-export\Goodbye.WordPress\MysqlPostReader.cs:line 55
   at Goodbye.WordPress.MysqlPostReader.ReadPostsAsync(CancellationToken cancellationToken)+System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult()
   at Goodbye.WordPress.WordPressExporter.ExportAsync(CancellationToken cancellationToken) in D:\Code\wordpress-export\Goodbye.WordPress\WordPressExporter.cs:line 162
   at Goodbye.WordPress.WordPressExporter.ExportAsync(CancellationToken cancellationToken) in D:\Code\wordpress-export\Goodbye.WordPress\WordPressExporter.cs:line 162
   at Program.<Main>$(String[] args) in D:\Code\wordpress-export\Export\Program.cs:line 18
   at Program.<Main>(String[] args)

Code sample
https://github.com/abock/goodbye-wordpress/blob/master/Goodbye.WordPress/MysqlPostReader.cs#L51

string? originalPermalinkStructure = null;

using var connection = new MySqlConnection(ConnectionString);

try
{
    await connection.OpenAsync(cancellationToken);
}
catch (Exception e)
{
    throw new ConnectionFailedException(e);
}

Expected behavior
runs without exception and no error with old versions. I am expecting same behavior with new versions of MySqlConnector

@bgrainger
Copy link
Member

Does your connection string contain multiple host names?

@bgrainger
Copy link
Member

There's a retry loop for SSL; it seems possible that this error could occur if the first TLS handshake (for TLS 1.2) fails and the client tries again.

@bgrainger
Copy link
Member

I was able to reproduce this by connecting to a server that only supports TLS 1.1; the exception is thrown when internally retrying the connection.

You should be able to work around it by adding ; TLS Version = TLS 1.1 to your connection string.

Thanks for reporting the problem!

@bgrainger bgrainger self-assigned this Nov 7, 2021
@bgrainger bgrainger added the bug label Nov 7, 2021
@bgrainger bgrainger added this to the 2.0 milestone Nov 7, 2021
@atiq-cs
Copy link
Author

atiq-cs commented Nov 8, 2021

I see what you mean. Thanks for the hint.

My problem is solved. I am adding some testing results, just, for the record.

Tls Version 1.1 doesn't work with this mysql database server we are using. 1.0 works for this one. So, I appended following with the connection string,

";TlsVersion=TLS 1.0";

I tried few things with the database server (MySqlConnector version 2.0.0-rc.1). I found following,

  • version 2.0.0-rc.1 seems to use TLS 1.2 by default which generated the error in bug description.
  • If I pass 1.3 I get slightly different error which is below,
$ dotnet run
Unhandled exception. Goodbye.WordPress.ConnectionFailedException: SSL Authentication Error
 ---> MySqlConnector.MySqlException (0x80004005): SSL Authentication Error
 ---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
 ---> System.ComponentModel.Win32Exception (0x80090331): The client and server cannot communicate, because they do not possess a common algorithm.
   --- End of inner exception stack trace ---
   at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm)
   at MySqlConnector.Core.ServerSession.InitSslAsync(ProtocolCapabilities serverCapabilities, ConnectionSettings cs, MySqlConnection connection, SslProtocols sslProtocols, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 1418
   at MySqlConnector.Core.ServerSession.InitSslAsync(ProtocolCapabilities serverCapabilities, ConnectionSettings cs, MySqlConnection connection, SslProtocols sslProtocols, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 1461
   at MySqlConnector.Core.ServerSession.ConnectAsync(ConnectionSettings cs, MySqlConnection connection, Int32 startTickCount, ILoadBalancer loadBalancer, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 485
   at MySqlConnector.Core.ConnectionPool.ConnectSessionAsync(MySqlConnection connection, String logMessage, Int32 startTickCount, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ConnectionPool.cs:line 363
   at MySqlConnector.Core.ConnectionPool.GetSessionAsync(MySqlConnection connection, Int32 startTickCount, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ConnectionPool.cs:line 94
   at MySqlConnector.Core.ConnectionPool.GetSessionAsync(MySqlConnection connection, Int32 startTickCount, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ConnectionPool.cs:line 124
   at MySqlConnector.MySqlConnection.CreateSessionAsync(ConnectionPool pool, Int32 startTickCount, Nullable`1 ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlConnection.cs:line 911
   at MySqlConnector.MySqlConnection.OpenAsync(Nullable`1 ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlConnection.cs:line 405
   at Goodbye.WordPress.MysqlPostReader.ReadPostsAsync(CancellationToken cancellationToken)+MoveNext() in D:\Code\wordpress-export\Goodbye.WordPress\MysqlPostReader.cs:line 51
   --- End of inner exception stack trace ---
   at Goodbye.WordPress.MysqlPostReader.ReadPostsAsync(CancellationToken cancellationToken)+MoveNext() in D:\Code\wordpress-export\Goodbye.WordPress\MysqlPostReader.cs:line 55
   at Goodbye.WordPress.MysqlPostReader.ReadPostsAsync(CancellationToken cancellationToken)+System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult()
   at Goodbye.WordPress.WordPressExporter.ExportAsync(CancellationToken cancellationToken) in D:\Code\wordpress-export\Goodbye.WordPress\WordPressExporter.cs:line 162
   at Goodbye.WordPress.WordPressExporter.ExportAsync(CancellationToken cancellationToken) in D:\Code\wordpress-export\Goodbye.WordPress\WordPressExporter.cs:line 162
   at Program.<Main>$(String[] args) in D:\Code\wordpress-export\Export\Program.cs:line 18

When I try TLS Version 1.1 I get following,

Unhandled exception. Goodbye.WordPress.ConnectionFailedException: The server doesn't support the client's specified TLS versions.
 ---> MySqlConnector.MySqlException (0x80004005): The server doesn't support the client's specified TLS versions.
 ---> System.ComponentModel.Win32Exception (0x80090331): The client and server cannot communicate, because they do not possess a common algorithm.
   at System.Net.SSPIWrapper.AcquireCredentialsHandle(ISSPIInterface secModule, String package, CredentialUse intent, SCH_CREDENTIALS* scc)
   at System.Net.Security.SslStreamPal.AcquireCredentialsHandle(CredentialUse credUsage, SCH_CREDENTIALS* secureCredential)
   at System.Net.Security.SslStreamPal.AcquireCredentialsHandleSchCredentials(X509Certificate2 certificate, SslProtocols protocols, EncryptionPolicy policy, Boolean isServer)
   at System.Net.Security.SslStreamPal.AcquireCredentialsHandle(SslStreamCertificateContext certificateContext, SslProtocols protocols, EncryptionPolicy policy, Boolean isServer)
   at System.Net.Security.SecureChannel.AcquireClientCredentials(Byte[]& thumbPrint)
   at System.Net.Security.SecureChannel.GenerateToken(ReadOnlySpan`1 inputBuffer, Byte[]& output)
   at System.Net.Security.SecureChannel.NextMessage(ReadOnlySpan`1 incomingBuffer)
   at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm)
   at MySqlConnector.Core.ServerSession.InitSslAsync(ProtocolCapabilities serverCapabilities, ConnectionSettings cs, MySqlConnection connection, SslProtocols sslProtocols, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 1418
   at MySqlConnector.Core.ServerSession.InitSslAsync(ProtocolCapabilities serverCapabilities, ConnectionSettings cs, MySqlConnection connection, SslProtocols sslProtocols, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 1465
   at MySqlConnector.Core.ServerSession.ConnectAsync(ConnectionSettings cs, MySqlConnection connection, Int32 startTickCount, ILoadBalancer loadBalancer, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 485
   at MySqlConnector.Core.ConnectionPool.ConnectSessionAsync(MySqlConnection connection, String logMessage, Int32 startTickCount, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ConnectionPool.cs:line 363
   at MySqlConnector.Core.ConnectionPool.GetSessionAsync(MySqlConnection connection, Int32 startTickCount, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ConnectionPool.cs:line 94
   at MySqlConnector.Core.ConnectionPool.GetSessionAsync(MySqlConnection connection, Int32 startTickCount, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ConnectionPool.cs:line 124
   at MySqlConnector.MySqlConnection.CreateSessionAsync(ConnectionPool pool, Int32 startTickCount, Nullable`1 ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlConnection.cs:line 911
   at MySqlConnector.MySqlConnection.OpenAsync(Nullable`1 ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlConnection.cs:line 405
   at Goodbye.WordPress.MysqlPostReader.ReadPostsAsync(CancellationToken cancellationToken)+MoveNext() in D:\Code\wordpress-export\Goodbye.WordPress\MysqlPostReader.cs:line 51
   --- End of inner exception stack trace ---
   at Goodbye.WordPress.MysqlPostReader.ReadPostsAsync(CancellationToken cancellationToken)+MoveNext() in D:\Code\wordpress-export\Goodbye.WordPress\MysqlPostReader.cs:line 55
   at Goodbye.WordPress.MysqlPostReader.ReadPostsAsync(CancellationToken cancellationToken)+System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult()
   at Goodbye.WordPress.WordPressExporter.ExportAsync(CancellationToken cancellationToken) in D:\Code\wordpress-export\Goodbye.WordPress\WordPressExporter.cs:line 162
   at Goodbye.WordPress.WordPressExporter.ExportAsync(CancellationToken cancellationToken) in D:\Code\wordpress-export\Goodbye.WordPress\WordPressExporter.cs:line 162

@bgrainger
Copy link
Member

version 2.0.0-rc.1 seems to use TLS 1.2 by default

So do earlier versions of MySqlConnector; it's just that before #1037 the internal retry loop (to downgrade TLS versions) didn't cause the exception you were seeing (but it was still happening).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants