Unable to resolve service for type 'DiLab.IClock' while attempting to activate 'DiLab.GreetingService'. — a constructor asked for a type that was never registered with dependency injection. Register the first type in the message in Program.cs and the error goes away.

Read the message as two names. The first is what is missing; the second is the class whose constructor asked for it. In the lab the whole fix was one line before builder.Build(): builder.Services.AddSingleton<IClock, SystemClock>();

The error

In the Development environment the app refuses to start:

Unhandled exception. System.AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: DiLab.GreetingService Lifetime: Scoped ImplementationType: DiLab.GreetingService': Unable to resolve service for type 'DiLab.IClock' while attempting to activate 'DiLab.GreetingService'.)
 ---> System.InvalidOperationException: Error while validating the service descriptor 'ServiceType: DiLab.GreetingService Lifetime: Scoped ImplementationType: DiLab.GreetingService': Unable to resolve service for type 'DiLab.IClock' while attempting to activate 'DiLab.GreetingService'.
 ---> System.InvalidOperationException: Unable to resolve service for type 'DiLab.IClock' while attempting to activate 'DiLab.GreetingService'.

In Production the same app starts, and the first request gets an empty 500 while the log says:

fail: Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HNOQN7ODQHMQ", Request id "0HNOQN7ODQHMQ:00000001": An unhandled exception was thrown by the application.
      System.InvalidOperationException: Unable to resolve service for type 'DiLab.IClock' while attempting to activate 'DiLab.GreetingService'.

Why it happens

ASP.NET Core builds every service you ask for through its container. When the endpoint needs a GreetingService, the container reads its constructor, finds an IClock parameter, and looks for a registration of IClock. There is none, and an interface cannot be created on its own, so it stops. The usual causes are a forgotten Add… line, or registering the class while the constructor asks for the interface.

public class GreetingService(IClock clock)
{
    public string Greet(string name) =>
        clock.Now.Hour < 12 ? $"Good morning, {name}" : $"Good afternoon, {name}";
}

The environment decides when you find out. In Development the host checks every registration when builder.Build() runs, so a missing one stops the app with the broken service named. In Production that check is off, the app starts, and the error waits for the first request that needs the service. You can switch the check on everywhere; with this in place, the lab failed at startup in Production too:

builder.Host.UseDefaultServiceProvider(options =>
{
    options.ValidateOnBuild = true;
    options.ValidateScopes = true;
});

The fix

using DiLab;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSingleton<IClock, SystemClock>();
builder.Services.AddScoped<GreetingService>();

var app = builder.Build();

app.MapGet("/", (GreetingService greetings) => greetings.Greet("Maria Garcia"));

app.Run();

The new line tells the container which class to build when something asks for IClock. The lifetime is part of the decision. AddSingleton makes one instance for the life of the app, right for SystemClock because it holds no state. AddScoped makes one per request, the normal choice for anything that uses a DbContext. AddTransient makes a new one every time it is asked for. Pick the lifetime by what the class holds, not by what makes the error go away: a singleton that depends on a scoped service fails with a different message.

How it was reproduced

A minimal API from dotnet new web -o DiLab on .NET SDK 10.0.401 (ASP.NET Core runtime 10.0.12, no extra packages): an IClock interface with a SystemClock class, a GreetingService that takes IClock in its primary constructor, registered with AddScoped, and a GET / endpoint that takes the service. Only IClock was left unregistered. The built app was started with ASPNETCORE_ENVIRONMENT set to Development, then Production, and called with curl. After the fix, GET / returned 200 with "Good morning, Maria Garcia" in both environments.

Frequently asked

What does 'Unable to resolve service for type' mean in ASP.NET Core?
A class asked for a type in its constructor and the dependency injection container has no registration for that type. The first type in the message is the missing registration; the second is the class that asked for it. Register the first one in Program.cs before builder.Build().
Why does my ASP.NET Core app start in Production but fail on the first request?
In Development the host validates every registration when the app is built, so a missing one stops startup. Production skips that check, so the error only appears when a request needs the broken service. Set ValidateOnBuild and ValidateScopes to true with builder.Host.UseDefaultServiceProvider to check in every environment.
Should I use AddSingleton, AddScoped or AddTransient?
Use a singleton for stateless, thread-safe helpers such as a clock, scoped for anything that uses a DbContext or holds data for one request, and transient for light objects that should never be shared. Choose by what the class holds, not by which registration silences the error.

More decoded errors in the Fixes category. For singleton, scoped and transient in plain words, see Services and Dependency Injection in Blazor.