While developing an ASP.NET Core Web API using Entity Framework Core and SQL Server, one of the most common migration errors developers encounter is:
A network-related or instance-specific error occurred while establishing a connection to SQL Server.
(provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
Error Number:2, State:0, Class:20
This error usually appears while executing:
Update-Database
or
dotnet ef database update
Although the message appears to indicate a network issue, the actual root cause is often related to SQL Server configuration, an incorrect connection string, startup project selection, or Entity Framework Core design-time configuration.
This article explains the complete troubleshooting process used by professional .NET developers to diagnose and resolve this issue.
Understanding the Error
When Entity Framework Core executes a migration, it attempts to establish a connection with SQL Server.
If SQL Server cannot be reached using the configured connection string, the following exception is thrown:
(provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
This does not necessarily mean SQL Server is unavailable. It simply means the application could not establish a connection.
Step 1 – Verify SQL Server Service
First, verify that SQL Server is installed and running.
Open Command Prompt and execute:
sc query MSSQL$SQLEXPRESS
Expected Output:
SERVICE_NAME: MSSQL$SQLEXPRESS
TYPE : 10 WIN32_OWN_PROCESS
STATE : 4 RUNNING
(STOPPABLE, PAUSABLE, ACCEPTS_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0
If the service is stopped:
services.msc
Step 2 – Verify SQL Server Connectivity
Before debugging your application, verify that SQL Server itself is accessible.
List Installed SQL Server Instances
sqlcmd -L
Example Output:
Servers:
DEV-SERVER\SQLEXPRESS
If no server is listed, SQL Server Browser may not be running or your SQL Server instance may not be discoverable.
Connect to SQL Server
sqlcmd -S .\SQLEXPRESS -E
or
sqlcmd -S DEV-SERVER\SQLEXPRESS -E
Successful connection:
1>
This confirms:
SQL Server is installed
SQL Server service is running
Windows Authentication is working
SQL Server accepts connections
Step 3 – Verify SQL Server Information
After connecting successfully, execute the following SQL commands in cmd .
Check Connected Server
SELECT @@SERVERNAME;
2> GO click enter
Output
--------------------------------------------------------------------------------------------------------------------------------
DEV-SERVER\SQLEXPRESS
Check SQL Server Version
SeLECT @@VERSION;
2> GO click enter
Output
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Microsoft SQL Server 2022 (RTM) - 16.0.1000.6 (X64)
Oct 8 2022 05:58:25
Copyright (C) 2022 Microsoft Corporation
Express Edition (64-bit) on Windows 10 Pro 10.0 <X64> (Build 26200: ) (Hypervisor)
(1 rows affected)
Verify Current Database
SELECT DB_NAME();
GO
Expected:
master
List All Databases
SELECT name
2> FROM sys.databases
3> ORDER BY name;
4> GO click enter
Output
name
--------------------------------------------------------------------------------------------------------------------------------
1000SQLDB
model
msdb
SqlInDepth
SQLJourney
SQLPracticeQuery
tempdb
TestData
Verify Current Login
SELECT SYSTEM_USER;
2> GO click enter
Output
--------------------------------------------------------------------------------------------------------------------------------
DEV-SERVER\HP
(1 rows affected)
Verify Authentication Mode
SELECT SERVERPROPERTY('IsIntegratedSecurityOnly');
GO
Output:
| Value | Meaning |
|---|
| 1 | Windows Authentication Only |
| 0 | Mixed Authentication |
Exit sqlcmd
EXIT
Step 4 – Verify the Connection String
A large number of SQL Server connection issues are caused by incorrect connection strings.
Example:
{
"ConnectionStrings": {
"DefaultConnection": "Server=DEV-SERVER\\SQLEXPRESS;Database=SampleERPDB;Integrated Security=True;TrustServerCertificate=True;MultipleActiveResultSets=True"
}
}
Parameter Explanation
| Parameter | Description |
|---|
| Server | SQL Server instance |
| Database | Target database |
| Integrated Security | Windows Authentication |
| TrustServerCertificate | Skip SSL validation for development |
| MultipleActiveResultSets | Allow multiple active result sets |
The Server value should match the value returned by:
SELECT @@SERVERNAME;
GO
Step 5 – Register DbContext Correctly
Register Entity Framework Core inside the Infrastructure layer.
services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseSqlServer(
configuration.GetConnectionString("DefaultConnection"),
sql =>
{
sql.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName);
});
});
Avoid multiple DbContext registrations.
Step 6 – Verify Dependency Injection
Your API should register both Application and Infrastructure services.
builder.Services.AddApplication();
builder.Services.AddInfrastructure(builder.Configuration);
This ensures the DbContext receives the correct configuration.
Step 7 – Verify Startup Project
Incorrect startup project selection is one of the most common causes of migration failures.
Startup Project
SampleERP.API
Default Project
SampleERP.Infrastructure
When using Visual Studio Package Manager Console:
Step 8 – Verify appsettings.Development.json
ASP.NET Core loads configuration in this order:
appsettings.json
appsettings.Development.json
Environment Variables
User Secrets
If appsettings.Development.json contains another connection string, it overrides appsettings.json.
Example:
{
"ConnectionStrings": {
"DefaultConnection": "Server=OLD-SERVER\\SQLEXPRESS;Database=OldDatabase;"
}
}
Always verify both files.
Step 9 – Check Design-Time DbContext Factory
Search your solution for:
IDesignTimeDbContextFactory
or
ApplicationDbContextFactory
Example:
public class ApplicationDbContextFactory
: IDesignTimeDbContextFactory<ApplicationDbContext>
{
public ApplicationDbContext CreateDbContext(string[] args)
{
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
builder.UseSqlServer(
"Server=OLD-SERVER\\SQLEXPRESS;Database=OldDatabase;");
return new ApplicationDbContext(builder.Options);
}
}
During migrations, Entity Framework Core uses this factory instead of Program.cs.
Step 10 – Search for Multiple UseSqlServer Registrations
Search the entire solution:
UseSqlServer(
There should ideally be only one registration.
Step 11 – Display the Active Connection String
Temporarily print the active connection string.
var connectionString =
builder.Configuration.GetConnectionString("DefaultConnection");
Console.WriteLine(connectionString);
services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseSqlServer(connectionString);
});
If the printed value differs from the expected connection string, another configuration source is overriding it.
Step 12 – Verify SQL Server Browser Service
Open:
services.msc
Ensure the following service is running:
SQL Server Browser
Although optional for local development, it assists clients in locating named SQL Server instances.
SQL Server Health Check Commands
Run these commands after connecting via sqlcmd.
SELECT @@SERVERNAME;
GO
SELECT @@VERSION;
GO
SELECT SYSTEM_USER;
GO
SELECT DB_NAME();
GO
SELECT name
FROM sys.databases
ORDER BY name;
GO
If all commands execute successfully, SQL Server is healthy and accepting connections.
Common Root Causes
Most Error 40 issues are caused by one or more of the following:
Incorrect SQL Server instance name
SQL Server service is stopped
Invalid connection string
Wrong startup project
appsettings.Development.json overriding configuration
Hardcoded connection string inside IDesignTimeDbContextFactory
Multiple DbContext registrations
SQL Server Browser service stopped
Environment variables overriding configuration
Best Practices
Store connection strings in configuration files or secret stores.
Avoid hardcoding connection strings.
Keep only one DbContext registration.
Use dependency injection consistently.
Keep Entity Framework Core package versions aligned.
Use verbose logging during migration debugging.
Verify the startup project before running migrations.
Test SQL Server connectivity using sqlcmd or SQL Server Management Studio before debugging Entity Framework Core.
Before spending hours debugging, verify the following:
SQL Server service is running.
SQL Server instance name is correct.
Connection string is valid.
Database exists or migrations are ready to create it.
Startup project is correct.
DbContext registration is correct.
No configuration overrides exist.
Design-time DbContext factory uses the correct connection string.
TCP/IP is enabled.
SQL Server Browser service is running.
Conclusion
The "Named Pipes Provider, Error 40" exception is one of the most common SQL Server connectivity issues in ASP.NET Core applications.
In most cases, the problem is not SQL Server itself, but a configuration mismatch between the application, Entity Framework Core, and the SQL Server instance.
By following a structured troubleshooting approach—verifying SQL Server connectivity, validating the connection string, checking dependency injection, confirming the startup project, reviewing configuration files, and inspecting Entity Framework Core's design-time configuration—you can identify the root cause quickly and resolve it with confidence.
Always begin by confirming that SQL Server is reachable using sqlcmd or SQL Server Management Studio before investigating your application. A methodical process saves time, reduces frustration, and leads to faster, more reliable solutions.