Sqlclient: Could not load type 'System.Configuration.ConfigurationSection' from assembly 'System.Configuration.ConfigurationManager'

Created on 17 Nov 2020  路  21Comments  路  Source: dotnet/SqlClient

Describe the bug

If using Microsoft.Data.SqlClient without also manually adding a reference to System.Configuration.ConfigurationManager, a simple call to new SqlConnection with a raw connection string and then conn.Open() causes the following exception:

System.TypeInitializationException
  HResult=0x80131534
  Message=The type initializer for 'Microsoft.Data.SqlClient.SqlAuthenticationProviderManager' threw an exception.
  Source=Microsoft.Data.SqlClient
  StackTrace:
   at Microsoft.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, Boolean applyTransientFaultHandling, String accessToken, DbConnectionPool pool)
   at Microsoft.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
   at Microsoft.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
   at Microsoft.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at Microsoft.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at Microsoft.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry, SqlConnectionOverrides overrides)
   at Microsoft.Data.SqlClient.SqlConnection.Open(SqlConnectionOverrides overrides)
   at Microsoft.Data.SqlClient.SqlConnection.Open()
   at Test.Program.Main(String[] args) in D:\Desktop\Test\Test\Program.cs:line 11

Inner Exception 1:
TypeLoadException: Could not load type 'System.Configuration.ConfigurationSection' from assembly 'System.Configuration.ConfigurationManager, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.

To reproduce

Repro solution: Repro.zip

The important code:

c# using (var conn = new SqlConnection("Data Source=(LocalDb)\\MSSQLLocalDB;Initial Catalog=MyDb;Integrated Security=True")) { conn.Open(); }

Adding a reference to System.Configuration.ConfigurationManager 5.0.0 (and probably earlier versions, too) fixes the error.

I'm confused about two things:

  • If Microsoft.Data.SqlClient depends on System.Configuration.ConfigurationManager, why isn't this in the nuspec, so that System.Configuration.ConfigurationManager is installed alongside Microsoft.Data.SqlClient?
  • Why does Microsoft.Data.SqlClient use the configuration system at all when I just pass a raw connection string? Surely this isn't necessary?

Expected behavior

The code runs without issues.

Further technical details

Microsoft.Data.SqlClient version: 2.0.1
.NET target: netcoreapp3.1
SQL Server version: Not important
Operating system: Windows

Most helpful comment

Excellent tip, I should have thought of that! That fixed the problem.

All 21 comments

Unable to repro

Which environmental factors could this depend on? The code is trivial, so I'm lost. I tried adding a global.json with different SDKs, but I get the same result for all versions I tried.

Do you have an app.config file in the project?

No app.config. Did you try the repro solution I attached? There you can see exactly what's there and not.

I did, and was unable to repro.

FWIW I too am unable to repro on another computer. Still, I have no clue why it fails on this computer or how to debug it (I have already spent some hours googling, without finding anything relevant). Do you have any insights to share that can help me debug this further? Could machine.config come into play? I don't know anything about that file or whether it's relevant for .NET Core, just throwing it out there.

Also, are you able to answer the following two questions from the OP?

I'm confused about two things:

  • If Microsoft.Data.SqlClient depends on System.Configuration.ConfigurationManager, why isn't this in the nuspec, so that System.Configuration.ConfigurationManager is installed alongside Microsoft.Data.SqlClient?

  • Why does Microsoft.Data.SqlClient use the configuration system at all when I just pass a raw connection string? Surely this isn't necessary?

In case it can point somewhere, here are all the environment variables and PATH values.

image

image

image

@cmeeren

If Microsoft.Data.SqlClient depends on System.Configuration.ConfigurationManager, why isn't this in the nuspec, so that System.Configuration.ConfigurationManager is installed alongside Microsoft.Data.SqlClient?

Microsoft.Data.SqlClient (.NET Core 2.1+) depends on System.Configuration.ConfigurationManager, please view NuGet.org dependencies here: https://www.nuget.org/packages/Microsoft.Data.SqlClient
image

Why does Microsoft.Data.SqlClient use the configuration system at all when I just pass a raw connection string? Surely this isn't necessary?

This is a long time behavior that SqlClient supports since System.Data.SqlClient (.NET Framework), and has advanced to support different configuration sections. It may not be necessary in your case, but to our other customers this is important.

Microsoft.Data.SqlClient (.NET Core 2.1+) depends on System.Configuration.ConfigurationManager, please view NuGet.org dependencies here: https://www.nuget.org/packages/Microsoft.Data.SqlClient

Sorry, my bad. I notice that it doesn't depend on it for netstandard2.0, but I guess that's not a problem.

I notice that after I build the repro solution, System.Configuration.ConfigurationManager.dll is indeed in my build output directory. Are you aware of what could cause the assembly to fail to load? Or anything that could remediate the issue, short of reinstalling Windows? (I realize I'm asking for help to debug/fix my environment; you don't have to spend any time on it, I'm just wondering if you have something on the top of your head.)

You may wanna ask that to the team who maintains the ConfigurationManager library (dotnet/runtime), we haven't heard of any related problems, so can't provide any ideas there.

For what it's worth - we're tracking down the same problem as reported here while trying to update dependencies on the Stack Overflow build, will add info as we can.

Importantly: we are only seeing this on Linux. Our Windows builds are fine.

I'm commenting on a closed issue here because users finding this are likely updating the client, not a downstream library. In our case, changing Microsoft.Data.SqlClient from 2.0.0-preview1.20021.1 to 2.0.1 (that's the _only_ difference) is what brings in the load exception. FWIW, 2.1.0 has the same behavior/issue here.

Our stack:

System.TypeInitializationException: The type initializer for 'Microsoft.Data.SqlClient.SqlAuthenticationProviderManager' threw an exception.
---> System.IO.FileLoadException: Could not load file or assembly 'System.Configuration.ConfigurationManager, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. Could not find or load a specific file. (0x80131621)
File name: 'System.Configuration.ConfigurationManager, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'
---> System.IO.FileLoadException: Could not load file or assembly 'System.Configuration.ConfigurationManager, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.
    at System.Runtime.Loader.AssemblyLoadContext.LoadFromPath(IntPtr ptrNativeAssemblyLoadContext, String ilPath, String niPath, ObjectHandleOnStack retAssembly)
    at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
    at System.Reflection.Assembly.LoadFrom(String assemblyFile)
    at System.Reflection.Assembly.LoadFromResolveHandler(Object sender, ResolveEventArgs args)
    at System.Runtime.Loader.AssemblyLoadContext.InvokeResolveEvent(ResolveEventHandler eventHandler, RuntimeAssembly assembly, String name)
    at System.Runtime.Loader.AssemblyLoadContext.OnAssemblyResolve(RuntimeAssembly assembly, String assemblyFullName)

    --- End of inner exception stack trace ---
    at Microsoft.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, Boolean applyTransientFaultHandling, String accessToken, DbConnectionPool pool) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs:line 474
    at Microsoft.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs:line 133
    at Microsoft.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions) in /_/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs:line 138
    at Microsoft.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs:line 726
    at Microsoft.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs:line 1737
    at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs:line 1147
    at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs:line 1115
    at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs:line 121
    at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions) in /_/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs:line 338
    at Microsoft.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions) in /_/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionClosed.cs:line 39
    at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry, SqlConnectionOverrides overrides) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs:line 1687
    at Microsoft.Data.SqlClient.SqlConnection.Open(SqlConnectionOverrides overrides) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs:line 1183
    at Microsoft.Data.SqlClient.SqlConnection.Open() in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs:line 1163
    at Dapper.SqlMapper.QueryImpl[T](IDbConnection cnn, CommandDefinition command, Type effectiveType)+MoveNext() in /_/Dapper/SqlMapper.cs:line 1083
    at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
    at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
    at Dapper.SqlMapper.Query[T](IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType) in /_/Dapper/SqlMapper.cs:line 725
    at Submission#0.FromDB() in /home/teamcity/buildAgent/work/e84222d4ca758600/StackOverflow.Localization/PrecompiledLocalizationDictionary.Generator.csx:line 126
    at Submission#0.<<Initialize>>d__0.MoveNext() in /home/teamcity/buildAgent/work/e84222d4ca758600/StackOverflow.Localization/PrecompiledLocalizationDictionary.Generator.csx:line 49

Thanks for the context @NickCraver
Then it would be something we need to check and it sounds like something introduced in our recent changes.

Reopening issue for further investigation.

I have some further info: In my repro solution, for things to work on my end, the System.Configuration.ConfigurationManager version must be 5.0.0, not 4.7.0, even though 4.7.0 should be supported by Microsoft.Data.SqlClient.

I observe the same behavior regardless of whether I use Microsoft.Data.SqlClient 2.0.0, 2.0.1, or 2.1.0. However, 1.1.3 works fine without a reference to System.Configuration.ConfigurationManager.

So I started looking at this since it was opened in dotnet/runtime. I haven't been able to repro by building on my computer... however I went ahead and looked at your repro so I started by inspecting the System.Configuration.ConfigurationManager assembly on ILSpy and it looks like the assembly on your bin folder is corrupt.

image

I don't feel safe running random binaries like this on my computer, but it seems like something corrupted that file.

Did you build your repro on the computer that you get the repro? Or are you deploying it to that computer? I looked at the corrupted binary digital signature and information and everything seems correct.

Also, looked at assets.json, and the file is correctly gathered from the nuget package. So I downloaded the System.Configuration.ConfigurationManager (4.7.0) nupgk from NuGet and the binary there looks just fine.

Did you build your repro on the computer that you get the repro?

Correct. It's my personal home computer. Do you have any idea what could cause this corruption?

Hm, it seems that there are corrupt files on my PC, including some .NET SDK-related stuff. Please don't spend time on my issue before I come back with more info.

False alarm. Fixed the corrupt stuff and repaired VS, but the problem still persists.

When referencing System.Configuration.ConfigurationManager 5.0.0, ILSpy looks normal, but when not referencing it or when referencing 4.7.0, it uses assembly version 4.0.3.0 which looks corrupt in ILSpy as your screenshot shows.

@cmeeren could you try deleting your nuget cache and then try with the 4.7.0 again?

Excellent tip, I should have thought of that! That fixed the problem.

Closing issue in light of above discussions.

Was this page helpful?
0 / 5 - 0 ratings