# Unable to Create an Object of Type DbContext in EF Core: Causes and Fixes

You add an entity, run `dotnet ef migrations add AddOrders`, and the tooling stops dead:

```text
Unable to create an object of type 'AppDbContext'. For the different patterns
supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
```

If you are hitting "unable to create an object of type DbContext" in EF Core, the frustrating part is that your application runs perfectly. It starts, it serves requests, it queries the database. The failure only happens when the EF Core tools try to build your `DbContext` **at design time**, which is a completely different code path from the one your API uses at runtime. In production I have watched teams lose an afternoon to this because they kept debugging the runtime configuration, which was never the problem. This article walks through the six causes I actually see in real .NET 10 and EF Core 10 codebases, in the order worth checking them, plus the one fix that works when nothing else does.

Once the migration is unblocked, the next question is usually how migrations should be applied in a real deployment pipeline rather than from a developer laptop. That whole story, from `DbContext` configuration and Fluent API mapping through to running `MigrateAsync` at startup, is what [Chapter 3 of the ASP.NET Core Web API: Zero to Production course](https://aspnetcoreapi.codingdroplets.com/) builds out inside one working codebase, so you see the design-time and runtime halves side by side instead of in isolation.

[![ASP.NET Core Web API: Zero to Production](https://newsletter.codingdroplets.com/images/aspnet-core-api-course-banner-1.jpg align="center")](https://aspnetcoreapi.codingdroplets.com/)

Some of the fixes below are one-liners, others change how your solution is wired together. If you want the reference implementation with the design-time factory, the multi-project layout, and the migration bundle all connected and running, that lives on [Patreon](https://www.patreon.com/CodingDroplets) as annotated source you can clone and adapt rather than reassemble from snippets.

## What Does "Unable to Create an Object of Type DbContext" Actually Mean?

It means the EF Core command-line tools could not construct an instance of your `DbContext` class. Migrations are generated by reading your model, and reading your model requires a live `DbContext` object. The tools never see your running application, so they try three strategies in a fixed order.

1.  **From application services.** The tools build and execute your startup project, grab the host's service provider, and resolve the `DbContext` from it. This is the path a default ASP.NET Core project takes.
    
2.  **From a parameterless constructor.** If step 1 fails, the tools look for your derived `DbContext` type in the target project and try `new AppDbContext()`. This only works when the context configures itself in `OnConfiguring`.
    
3.  **From a design-time factory.** If a class implementing `IDesignTimeDbContextFactory<TContext>` exists in the target project or the startup project, the tools skip everything else and use it.
    

The error message appears when all applicable strategies fail. Critically, the message you see first is the *outer* one. The real reason is an inner exception the tools swallow by default, which is why the first thing to do is never guess.

## How Do You See the Real Error Behind the Message?

Add the `--verbose` flag. The tools then print the full inner exception chain instead of the generic summary:

```bash
dotnet ef migrations add AddOrders --verbose
```

Nine times out of ten the answer is sitting in that output: a `SqlException`, a null reference from `OnModelCreating`, an `InvalidOperationException` about an unregistered service, or a missing configuration key. Read the innermost exception, not the outermost one. Everything below is easier to diagnose once you have it.

## Cause 1: The Startup Project Is the Wrong Project

This is the single most common cause in any layered solution. Your `DbContext` lives in an Infrastructure or Data class library, your host lives in an API project, and you run `dotnet ef` from the library folder. The tools then treat the class library as both the target project and the startup project. A class library has no host, so strategy 1 never runs, and if your context has no parameterless constructor, strategy 2 fails too.

The tools distinguish two projects. The **target project** is where migration files get written. The **startup project** is the one they build and execute to obtain configuration and services. Point them at the right pair explicitly:

```bash
dotnet ef migrations add AddOrders \
  --project src/Shop.Infrastructure \
  --startup-project src/Shop.Api
```

In the Visual Studio Package Manager Console, the equivalent is setting the API project as the solution's startup project and the Infrastructure project as the Default Project in the console dropdown. Getting only one of those two right is the classic half-fix that leaves the error in place.

If you have more than one `DbContext` in the solution, add `--context AppDbContext` as well, otherwise the tools fail with a different but equally unhelpful message about being unable to choose.

## Cause 2: Program.cs Throws Before the Host Is Built

This one surprises people. The EF Core tools do not statically analyze your startup project. They **run** it, up to the point the host is built. Any exception thrown before `builder.Build()` returns surfaces as the design-time error.

Typical culprits I have hit in production codebases:

*   A required configuration value read with `GetRequiredSection` or `["Key"]!` that only exists in the deployed environment
    
*   An Azure Key Vault or AWS Secrets Manager provider registered at startup that cannot authenticate from a developer machine
    
*   Eager validation via `ValidateOnStart()` on an options type whose values are not present locally
    
*   A synchronous health probe or warm-up call in the startup path
    

The tell is that the verbose output shows an exception that has nothing to do with EF Core. The fix is to make startup survive without external dependencies, usually by supplying local values through User Secrets and keeping fail-fast validation scoped to real environments:

```csharp
// Only enforce fail-fast validation outside of design time and local dev
if (!builder.Environment.IsDevelopment())
{
    builder.Services.AddOptions<PaymentOptions>()
        .Bind(builder.Configuration.GetSection("Payments"))
        .ValidateDataAnnotations()
        .ValidateOnStart();
}
```

Note that `dotnet ef` runs your app with `ASPNETCORE_ENVIRONMENT` resolved the normal way, so it usually picks up `Development`. You can force a different one by passing arguments through to the app after a `--` separator:

```bash
dotnet ef database update --startup-project src/Shop.Api -- --environment Staging
```

## Cause 3: The DbContext Cannot Be Resolved From the Container

If the verbose output contains a line like this, you are looking at a DI problem rather than a tooling problem:

```text
Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbContextOptions`1[Shop.Infrastructure.AppDbContext]'
while attempting to activate 'Shop.Infrastructure.AppDbContext'.
```

Your context has the standard options constructor:

```csharp
public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
}
```

That constructor is fine. The problem is that nothing registered `DbContextOptions<AppDbContext>` in the service provider the tools found. Either `AddDbContext<AppDbContext>` is missing entirely, or it lives in an extension method that the API project never calls, or it is registered conditionally behind an environment check that is false at design time. Register it unconditionally in the startup project's composition root:

```csharp
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("Default")));
```

A related trap: if you register the context with `AddDbContextFactory<T>` only, the tools looking for `AppDbContext` itself may not find what they need. The differences between these registration styles matter more than most teams expect, and I covered them in detail in [AddDbContext vs AddDbContextPool vs AddDbContextFactory](https://codingdroplets.com/adddbcontext-vs-adddbcontextpool-vs-adddbcontextfactory).

## Cause 4: The Connection String Is Missing at Design Time

Design time reads configuration from the **startup project**, not the project you are standing in. If your connection string lives in the API project's User Secrets but you run the command with the class library as the startup project, `GetConnectionString("Default")` returns null and `UseSqlServer(null)` throws.

Set the secret against the correct project and confirm it resolves:

```bash
dotnet user-secrets set "ConnectionStrings:Default" "Server=localhost;Database=Shop;Trusted_Connection=True;TrustServerCertificate=True" --project src/Shop.Api
dotnet ef dbcontext info --project src/Shop.Infrastructure --startup-project src/Shop.Api
```

`dotnet ef dbcontext info` is the cheapest possible smoke test. If it prints your provider and connection details, the design-time path is healthy and any remaining failure is in the model itself.

## Cause 5: The Tooling and Runtime Versions Are Out of Sync

A global `dotnet-ef` from an older major version cannot always load a newer EF Core runtime. The symptom is a strange inner exception, often a `MissingMethodException` or a type-load failure, rather than anything that mentions your code. Check what you actually have installed:

```bash
dotnet ef --version
```

Then align it with the `Microsoft.EntityFrameworkCore` version your projects reference. On .NET 10 with EF Core 10, that means the 10.x line:

```bash
dotnet tool update --global dotnet-ef
```

On a team, pin it instead of leaving it to whatever each machine happens to have. Declaring `dotnet-ef` as a local tool in `.config/dotnet-tools.json` and committing that file means `dotnet tool restore` gives everyone the identical version, which removes an entire category of "works on my machine" migration failures. This is one of the items on my [EF Core migration checklist for production teams](https://codingdroplets.com/ef-core-migration-checklist-production-dotnet-teams).

## Cause 6: Microsoft.EntityFrameworkCore.Design Is Missing

The design-time services live in a separate package, and it has to be referenced by the **startup project**. If it is only referenced by the Infrastructure library, the tools will tell you the startup project does not reference `Microsoft.EntityFrameworkCore.Design`. Add it where it belongs:

```bash
dotnet add src/Shop.Api package Microsoft.EntityFrameworkCore.Design
```

Keep it as a development-only dependency so it does not travel into your published output:

```xml
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.*">
  <PrivateAssets>all</PrivateAssets>
</PackageReference>
```

## The Fix That Always Works: IDesignTimeDbContextFactory

When the tools cannot reach a usable host, stop fighting the host. Implementing `IDesignTimeDbContextFactory<TContext>` bypasses strategies 1 and 2 entirely and hands EF Core exactly what it needs. Put it in the same project as your `DbContext`:

```csharp
public sealed class AppDbContextFactory : IDesignTimeDbContextFactory<AppDbContext>
{
    public AppDbContext CreateDbContext(string[] args)
    {
        var options = new DbContextOptionsBuilder<AppDbContext>()
            .UseSqlServer("Server=localhost;Database=Shop;Trusted_Connection=True;TrustServerCertificate=True")
            .Options;

        return new AppDbContext(options);
    }
}
```

Two things worth knowing before you reach for this. First, the connection string here is used only to build the model and generate migration files, so a local development database is fine. It is not the string your application uses at runtime. Second, because the factory short-circuits the other strategies, it will silently mask genuine startup problems in your API project. That is a real trade-off: I reach for it in class libraries, worker projects, and repositories with no obvious host, and I prefer fixing the startup project directly when one exists.

If you would rather not hardcode anything, read the string from an environment variable inside `CreateDbContext` and fail loudly when it is absent, so a misconfigured machine produces a clear message instead of a mysterious connection error.

## How Do You Stop This From Happening Again?

Four habits remove almost all repeat occurrences:

*   **Commit the exact command.** Put the full `dotnet ef migrations add` line with its `--project` and `--startup-project` flags into your README or a script. Nobody should be reconstructing it from memory.
    
*   **Pin the tool.** Use a local tool manifest so the tooling version is part of the repository, not part of each developer's machine.
    
*   **Keep startup dependency-free until the host is built.** Anything that needs a network call or a cloud secret belongs behind an environment check or in a hosted service, not in the straight-line path of `Program.cs`.
    
*   **Verify with** `dotnet ef dbcontext info` **in CI.** A ten-second check that the design-time path still resolves catches a broken migration setup before it blocks someone mid-feature.
    

Worth noting for the near future: EF Core 11, in preview at the time of writing, adds a `.config/dotnet-ef.json` file where `project`, `startupProject`, and `context` can be declared once for the whole repository. That turns the first habit above into something the tooling enforces rather than something people remember.

## FAQ

### Why does my application run fine but dotnet ef migrations add fail?

Because they use different code paths. Your application configures the `DbContext` through dependency injection at runtime. The EF Core tools build and execute your startup project separately to obtain a `DbContext` at design time, and that path can fail on a missing startup-project flag, a startup exception, or a missing configuration value that your deployed environment supplies.

### How do I see the real error behind "unable to create an object of type DbContext"?

Re-run the command with `--verbose`. The default output shows only the outer message, while verbose output prints the full inner exception chain. The innermost exception is almost always the actual cause and points directly at the fix.

### Do I need IDesignTimeDbContextFactory if my DbContext is in a class library?

Not necessarily. If the library is referenced by a host project, passing `--startup-project` at the host is usually enough and keeps design time consistent with runtime configuration. A design-time factory is the right answer when there is no host at all, or when the host cannot start on a developer machine.

### Why does EF Core say it cannot resolve DbContextOptions when adding a migration?

That inner exception means the tools found a service provider but `AddDbContext<TContext>` was never called on it, or was called conditionally in a branch that is false at design time. Register the context unconditionally in the startup project rather than inside an environment-specific block.

### Does the connection string in a design-time factory affect production?

No. It is used only to build the model and generate migration files. Applying migrations to a real database uses the connection supplied at that point, either from your application's runtime configuration, the `--connection` option, or a migration bundle. Still avoid committing production credentials into a factory class.

### Which project needs the Microsoft.EntityFrameworkCore.Design package?

The startup project, the one the tools build and run. Referencing it only from the project that contains the `DbContext` is a common mistake in layered solutions. Mark it with `<PrivateAssets>all</PrivateAssets>` so it stays a development-time dependency.

For the authoritative details on how the tools resolve your context, see the Microsoft documentation on [design-time DbContext creation](https://learn.microsoft.com/en-us/ef/core/cli/dbcontext-creation) and the [EF Core .NET CLI tools reference](https://learn.microsoft.com/en-us/ef/core/cli/dotnet).

* * *

## About the Author

I'm Celin Daniel, Co-founder of [Coding Droplets](https://codingdroplets.com/). I've been building .NET and ASP.NET Core systems in production for 13+ years - APIs, distributed backends, enterprise platforms. Everything I write here comes from real shipping experience: patterns that held up, trade-offs that bit us, and lessons learned the hard way.

*   GitHub: [codingdroplets](http://github.com/codingdroplets/)
    
*   YouTube: [Coding Droplets](https://www.youtube.com/@CodingDroplets)
    
*   Website: [codingdroplets.com](https://codingdroplets.com/)
