System.InvalidOperationException: The ConnectionString property has not been initialized.
means SqlConnection was given null or an empty string. In an ASP.NET Core
app that almost always comes from GetConnectionString("Default") finding nothing, because
the key in appsettings.json is not under a section named exactly ConnectionStrings.
Put the string under "ConnectionStrings": { "Default": "..." }, plural, and make the
code fail at the line that reads configuration, with the key's name in the message, instead of at
Open().
The error
Unhandled exception. System.InvalidOperationException: The ConnectionString property has not been initialized.
at Microsoft.Data.SqlClient.SqlConnection.PermissionDemand()
at Microsoft.Data.SqlClient.SqlConnectionFactory.PermissionDemand(DbConnection outerConnection)
...
at Microsoft.Data.SqlClient.SqlConnection.Open()
at Program.<Main>$(String[] args) in ...\CfgLab\Program.cs:line 7
It came from this code and this appsettings.json, with ConnectionString in the singular:
using var connection = new SqlConnection(builder.Configuration.GetConnectionString("Default"));
connection.Open();
{
"ConnectionString": {
"Default": "Server=(localdb)\\MSSQLLocalDB;Database=master;Integrated Security=true"
},
Why it happens
GetConnectionString("Default") is shorthand for reading
ConnectionStrings:Default from configuration. It looks in that one section and nowhere
else, and when the key is missing it returns null without complaint. The same
null came back when the key sat at the root of the file as "Default": "...",
outside any section: the value is in the file, just not where the method looks.
The SqlConnection constructor accepts the null too. Only
Open() checks the property, so the stack trace points at line 7, the Open()
call, while the real mistake is one line above and in a different file. That distance is what makes
this error slow to read.
The fix
{
"ConnectionStrings": {
"Default": "Server=(localdb)\\MSSQLLocalDB;Database=master;Integrated Security=true"
},
var connectionString = builder.Configuration.GetConnectionString("Default")
?? throw new InvalidOperationException("Connection string 'Default' was not found under ConnectionStrings in configuration.");
Console.WriteLine($"Same value by path: {connectionString == builder.Configuration["ConnectionStrings:Default"]}");
using var connection = new SqlConnection(connectionString);
connection.Open();
With the section renamed the app printed Same value by path: True and
Connected to (localdb)\MSSQLLocalDB, server version 16.00.1210, so
GetConnectionString("Default") and Configuration["ConnectionStrings:Default"]
return the same thing. Pick one spelling and keep the section name exact.
The ?? throw line is the part worth keeping. With the old singular section still in
place, the app now stopped with
Connection string 'Default' was not found under ConnectionStrings in configuration. at
line 6, which names both the key and the section to look in. That is the message you want a
colleague to see on a server where the file was copied by hand.
How it was reproduced
An empty web project (dotnet new web) with Microsoft.Data.SqlClient 7.1.1, on .NET SDK
10.0.403 with runtime 10.0.14, on Windows 11. The connection was opened at startup, before
app.Run(), to keep the trace short. Both broken layouts (singular section, key at the root)
gave the same exception; the fixed run connected to SQL Server LocalDB 16.0.1210. The project name and
key are the test's own.
Frequently asked
- Why does GetConnectionString return null in ASP.NET Core?
- It reads only the section named ConnectionStrings. If appsettings.json says ConnectionString in the singular, or the key sits at the root or in another section, the method finds nothing and returns null without an error.
- Is GetConnectionString the same as Configuration["ConnectionStrings:Default"]?
- Yes. In the test both returned the same string. GetConnectionString(name) is a shortcut for the ConnectionStrings:name path, so either works as long as the JSON uses that section.
- How do I make a missing connection string fail with a clear message?
- Add ?? throw new InvalidOperationException(...) after GetConnectionString and name the key and section in the message. The app then stops at the line that reads configuration instead of at Open().
Setting up the database itself? Databases on a dev PC walks through LocalDB, Express and PostgreSQL connection strings. More decoded errors in the Fixes category.