How to Fix .NET AI App Errors: Microsoft.Extensions.AI Setup

Microsoft Fix Intermediate 14 min read Official Docs Grounded Updated April 20, 2026

Why This Is Happening

If you're trying to build AI apps with .NET and running into walls , packages that won't resolve, IChatClient wiring that silently fails, Azure OpenAI connections that time out immediately, or Agent Framework orchestration that produces nothing , you're not alone. I've seen this exact cluster of problems on dozens of developer machines, and the root cause is almost never what the error message suggests.

The .NET AI ecosystem moved fast in 2025 and 2026. Microsoft reorganized the core abstractions out of Semantic Kernel and into the Microsoft.Extensions.AI namespace. That was the right architectural call, it created a genuine unified layer across providers, but it also meant that a lot of blog posts, Stack Overflow answers, and even some official samples are now pointing at the wrong package names, outdated method signatures, or deprecated configuration patterns. You copy a snippet that was correct six months ago and nothing builds.

There's also a naming confusion problem that catches people constantly. Microsoft.Extensions.AI is the abstractions layer. Microsoft Agent Framework is the higher-level orchestration layer that sits on top of it. Many developers install one when they actually need the other, or install both without understanding how they relate. The official docs are clear on this distinction, but the error messages you get when you mix them up are anything but clear.

On the authentication side, connecting .NET apps to Azure OpenAI is deceptively simple in the quickstart and maddening in a real enterprise environment. App registrations, managed identities, role assignments on the Azure OpenAI resource, if any one of those is missing or misconfigured, you'll get a generic 401 or 403 that tells you almost nothing about which layer broke.

And then there's the local model path. Running Ollama with Phi-3 or Mistral locally through Microsoft.Extensions.AI should work out of the box, and usually does, except when port bindings, model pull status, or the Ollama server startup sequence get in the way.

This guide walks through every layer: package selection, provider configuration, dependency injection wiring, authentication, and Agent Framework setup. Whatever's blocking you right now, we'll get past it. Browse all Microsoft fix guides →

The Quick Fix, Try This First

Eighty percent of "my .NET AI app won't work" problems come down to one thing: wrong or missing NuGet packages. Before you spend an hour chasing authentication configs or DI registration issues, verify your package references are correct.

Open your terminal in the project directory and run this:

dotnet list package | grep -i "Extensions.AI\|Agent"

If you're on Windows PowerShell:

dotnet list package | Select-String "Extensions.AI","Agent"

What you should see depends on what you're building. For a basic chat application that talks to a single AI provider, you need Microsoft.Extensions.AI plus your provider-specific package. For agentic workflows with multi-step orchestration, you need Microsoft Agent Framework packages instead of managing IChatClient directly.

Here's the correct package set for the most common scenario, an Azure OpenAI-backed chat app:

dotnet add package Microsoft.Extensions.AI
dotnet add package Azure.AI.OpenAI
dotnet add package Microsoft.Extensions.AI.OpenAI

For OpenAI direct (not Azure-hosted):

dotnet add package Microsoft.Extensions.AI
dotnet add package OpenAI
dotnet add package Microsoft.Extensions.AI.OpenAI

For local models via Ollama:

dotnet add package Microsoft.Extensions.AI
dotnet add package Microsoft.Extensions.AI.Ollama

After adding the packages, do a full restore and rebuild:

dotnet restore
dotnet build

If the build succeeds and your IChatClient type resolves without red underlines in Visual Studio or VS Code, you've cleared the most common blocker. Move on to the steps below to wire up your configuration correctly.

Pro Tip
Don't add Microsoft.Extensions.AI.Abstractions directly unless you're building a library that other developers will consume. Application code should reference Microsoft.Extensions.AI (the full package) or the Agent Framework packages, the abstractions package alone gives you interfaces with no concrete implementations, which produces confusing "no service registered for IChatClient" errors at runtime even when everything looks correct at compile time.
1
Verify and Install the Correct Microsoft.Extensions.AI NuGet Packages

Let's be methodical here. Open your .csproj file directly, not the NuGet Package Manager UI, which can lag behind, and look at what's actually referenced.

<ItemGroup>
  <PackageReference Include="Microsoft.Extensions.AI" Version="9.*" />
  <PackageReference Include="Microsoft.Extensions.AI.OpenAI" Version="9.*" />
  <PackageReference Include="Azure.AI.OpenAI" Version="2.*" />
</ItemGroup>

The version numbers matter. Microsoft.Extensions.AI tracks with the .NET Extensions versioning scheme. The provider-specific packages (Microsoft.Extensions.AI.OpenAI, Microsoft.Extensions.AI.Ollama) must be compatible with your base Microsoft.Extensions.AI version. Mismatched minor versions across these packages is a frequent source of assembly binding failures that show up as MissingMethodException or TypeLoadException at runtime, not at build time, which makes them especially frustrating to diagnose.

Run dotnet nuget locals all --list to see your local package cache locations. If you've been working with pre-release builds, stale cached packages can override your intended versions. Clear the cache with:

dotnet nuget locals all --clear

Then restore fresh:

dotnet restore --no-cache

One more thing: if you're in a corporate environment with a private NuGet feed, make sure nuget.config includes https://api.nuget.org/v3/index.json as a source. Some enterprise feeds are configured as exclusive sources that block public packages entirely, and the error message ("package not found") looks identical to a typo in the package name.

When this step works, dotnet build completes without CS0246 ("type or namespace not found") errors on any Microsoft.Extensions.AI types.

2
Configure Your AI Provider Connection String and Credentials

The second most common failure point when you build AI apps with .NET is credentials, either hardcoded in the wrong place, missing from environment variables at runtime, or structured for one provider when you're actually targeting another.

Never put API keys in appsettings.json committed to source control. Use appsettings.Development.json (which should be in .gitignore) for local development, or better yet, the .NET Secret Manager:

dotnet user-secrets init
dotnet user-secrets set "OpenAI:ApiKey" "sk-your-key-here"
dotnet user-secrets set "AzureOpenAI:Endpoint" "https://your-resource.openai.azure.com/"
dotnet user-secrets set "AzureOpenAI:ApiKey" "your-azure-key"

For Azure OpenAI, you also need the deployment name, this is not the model name like "gpt-4o", it's the name you gave your deployment inside the Azure AI Foundry portal. These are often different and the error when they don't match is a 404 that looks like a connectivity problem:

dotnet user-secrets set "AzureOpenAI:DeploymentName" "my-gpt4o-deployment"

In your Program.cs, read configuration cleanly before registering services:

var builder = WebApplication.CreateBuilder(args);

var endpoint = builder.Configuration["AzureOpenAI:Endpoint"]
    ?? throw new InvalidOperationException("AzureOpenAI:Endpoint is not set");
var deploymentName = builder.Configuration["AzureOpenAI:DeploymentName"]
    ?? throw new InvalidOperationException("AzureOpenAI:DeploymentName is not set");

The explicit null-check with a descriptive exception message means you get a meaningful startup error instead of a cryptic NullReferenceException buried in a stack frame that points at the .NET AI internals.

For GitHub Models, which lets you access a range of models through GitHub's AI model marketplace, the configuration is the same structure as OpenAI direct, but the endpoint points to https://models.inference.ai.azure.com and you use a GitHub Personal Access Token instead of an OpenAI key. That mismatch in mental model catches people regularly.

You'll know this step is done correctly when builder.Build() succeeds without a configuration exception and your app starts cleanly.

3
Register IChatClient in Your Dependency Injection Container

This is where the Microsoft.Extensions.AI abstractions layer really earns its place. The IChatClient interface is your application's single point of contact with any AI model, swap the provider by changing one registration line, and nothing else in your application needs to change. That's the architecture goal, and it works when the DI registration is correct.

Here's the minimal correct registration for Azure OpenAI:

using Azure.AI.OpenAI;
using Microsoft.Extensions.AI;

// Inside builder.Services setup:
var azureClient = new AzureOpenAIClient(
    new Uri(endpoint),
    new Azure.AzureKeyCredential(apiKey));

builder.Services.AddSingleton<IChatClient>(
    azureClient.AsChatClient(deploymentName));

For Ollama running locally on its default port:

builder.Services.AddSingleton<IChatClient>(
    new OllamaChatClient(new Uri("http://localhost:11434"), "phi3"));

The "phi3" here is the model name as Ollama knows it, run ollama list in a terminal to see exactly what's available on your machine. If you reference a model that hasn't been pulled, you'll get a connection-refused-style error because Ollama returns a non-2xx response, and the .NET AI client surfaces this as a generic HttpRequestException.

A common mistake is registering IChatClient as Transient when the underlying provider client is heavyweight and expensive to initialize. Singleton is correct for most scenarios. If you need per-request isolation (rare, but legitimate), use Scoped and understand that each request creates a new instance.

In a controller or Razor Page, inject it normally:

public class ChatController(IChatClient chatClient) : Controller
{
    public async Task<IActionResult> Ask(string prompt)
    {
        var response = await chatClient.CompleteAsync(prompt);
        return Ok(response.Message.Text);
    }
}

When this step is working, your application starts without InvalidOperationException: No service for type 'Microsoft.Extensions.AI.IChatClient' has been registered. That's the exact error text you're looking to eliminate.

4
Fix Azure OpenAI Authentication Errors (401, 403, Managed Identity)

Authentication is where .NET AI app setup gets genuinely tricky in real enterprise environments. The official documentation covers authenticating App Service to Azure OpenAI, and this is the path you should be on for any production workload, API keys in config files are a security liability at scale.

The production-correct approach uses a managed identity. In the Azure portal, navigate to your App Service → SettingsIdentitySystem assigned, and flip the toggle to On. Copy the Object (principal) ID that appears.

Now go to your Azure OpenAI resource → Access control (IAM)Add role assignment. Select the Cognitive Services OpenAI User role (not Contributor, least privilege matters here). In the Members tab, choose Managed identity, then select your App Service.

In your .NET code, swap the key credential for a DefaultAzureCredential:

using Azure.Identity;
using Azure.AI.OpenAI;

var azureClient = new AzureOpenAIClient(
    new Uri(endpoint),
    new DefaultAzureCredential());

DefaultAzureCredential is smart, in local development it tries your Azure CLI login, Visual Studio login, and environment variables in sequence. In production on App Service, it automatically picks up the managed identity. One code path, both environments.

If you get a 403 even with the role assigned, wait five minutes. Azure RBAC role assignments can take up to five minutes to propagate, and hitting the endpoint immediately after assignment is a classic "it's broken" moment that resolves on its own.

If you see error code AuthorizationFailed in the response body (not just a 403 HTTP status), the issue is at the resource level, the managed identity exists but wasn't granted the OpenAI User role on the correct resource scope. Double-check that you assigned the role on the Azure OpenAI resource specifically, not on the resource group or subscription (though those work too, they're broader than necessary).

For local development, run az login in your terminal before starting the app. If you have multiple subscriptions, run az account set --subscription "your-subscription-id" to make sure the right one is active.

5
Set Up Microsoft Agent Framework for Multi-Step AI Workflows

If you've gotten through steps 1–4 and your basic IChatClient works, but now you're building something more complex, multiple AI agents working together, tool calling, RAG pipelines, or any kind of orchestration, you need Microsoft Agent Framework. Using bare IChatClient for these scenarios is like writing a web app without a framework: possible, but you'll reinvent a lot of wheels badly.

Agent Framework is the production-ready open-source framework that brings together the best of Semantic Kernel and Microsoft Research's AutoGen work. It's built on top of Microsoft.Extensions.AI.Abstractions, so your provider knowledge from the previous steps transfers directly.

Add the Agent Framework packages:

dotnet add package Microsoft.AI.Agents
dotnet add package Microsoft.AI.Agents.OpenAI

Agent Framework gives you five orchestration patterns out of the box: sequential (agents run one after another), concurrent (agents run in parallel and results are merged), group chat (agents discuss and iterate), handoff (one agent transfers control to another based on conditions), and magentic (a lead agent directs other agents dynamically). Most real-world agentic applications need magentic or handoff patterns, and building those by hand with raw IChatClient calls is a significant engineering investment.

A minimal two-agent setup where a research agent hands off to a summary agent looks like this:

var kernel = Kernel.CreateBuilder()
    .AddAzureOpenAIChatCompletion(deploymentName, endpoint, apiKey)
    .Build();

var researchAgent = new ChatCompletionAgent
{
    Name = "Researcher",
    Instructions = "You find relevant facts and data about the given topic.",
    Kernel = kernel
};

var summaryAgent = new ChatCompletionAgent
{
    Name = "Summarizer",
    Instructions = "You take research notes and write a concise summary.",
    Kernel = kernel
};

Agent Framework also has built-in OpenTelemetry support, add your telemetry exporter and you immediately get traces for every agent invocation, tool call, and model response. In an enterprise environment, this observability is not optional. Without it, diagnosing why an agent workflow produces wrong outputs is guesswork.

When this step is working, you can see agent turn-by-turn traces in your telemetry backend and responses flowing through the orchestration chain correctly.

Advanced Troubleshooting

When the standard setup steps don't resolve your issue, it's time to dig into the lower-level signals. Here's what to look at.

Event Viewer and Application Logs

For .NET apps running on Windows, open Event Viewer (Win + Reventvwr.msc) and navigate to Windows LogsApplication. Filter by Source = .NET Runtime. Event IDs 1026 (application crash) and 5000 (application error) will contain the full exception type and stack trace that gets swallowed in generic error responses. This is especially useful for assembly binding failures that look like provider connection issues from the outside.

HTTP-Level Debugging with Fiddler or a Custom Handler

When you're not sure whether your credentials are reaching Azure OpenAI correctly, intercept the raw HTTP traffic. Add a logging HTTP message handler to the AzureOpenAIClient:

using Azure.Core.Pipeline;
using Azure.Core;

var options = new AzureOpenAIClientOptions();
options.Diagnostics.IsLoggingEnabled = true;
options.Diagnostics.IsLoggingContentEnabled = true; // NEVER in production

var client = new AzureOpenAIClient(new Uri(endpoint), credential, options);

Set IsLoggingContentEnabled to true only in a local dev environment, it logs full request and response bodies, which will include your prompts, completions, and potentially sensitive data.

Group Policy in Domain-Joined Enterprise Environments

In corporate environments, Group Policy can block outbound HTTPS to non-whitelisted endpoints. If your .NET AI app works on a personal machine but not on a domain-joined dev machine, open Group Policy Management Console (gpmc.msc) and look for policies under Computer ConfigurationWindows SettingsSecurity SettingsWindows Firewall. The Azure OpenAI endpoint (*.openai.azure.com) and Ollama's local port (11434) both need to be reachable. Work with your network team to whitelist these, don't try to bypass firewall rules.

Proxy Configuration

Corporate HTTP proxies can silently break HttpClient-based Azure SDK calls. Set the proxy explicitly if needed:

var httpClient = new HttpClient(new HttpClientHandler
{
    Proxy = new WebProxy("http://your-proxy:8080"),
    UseProxy = true
});

var options = new AzureOpenAIClientOptions();
options.Transport = new HttpClientTransport(httpClient);

Rate Limiting and Throttling (Error 429)

Azure OpenAI rate limits are per-deployment and configured in tokens-per-minute (TPM) and requests-per-minute (RPM). A 429 response means you've hit one of these limits. The response header Retry-After tells you how many seconds to wait. The Azure SDK includes automatic retry with exponential backoff, but you can tune it:

var options = new AzureOpenAIClientOptions();
options.Retry.MaxRetries = 5;
options.Retry.Delay = TimeSpan.FromSeconds(2);
options.Retry.MaxDelay = TimeSpan.FromSeconds(30);

If you're hitting 429s constantly in development, check your deployment's quota in Azure AI FoundryDeployments → select your deployment → Edit. Increase the TPM limit if your subscription quota allows it.

When to Call Microsoft Support

Escalate to Microsoft Support when: your managed identity role assignment is correct but you still get consistent 403 errors after 30+ minutes; your Azure OpenAI resource shows as healthy in the Azure portal but all API calls return 503; or you're seeing Agent Framework orchestration produce malformed outputs that don't match any known model limitation. These are symptoms of platform-level issues that no amount of local debugging will resolve. Open a support ticket with the correlation ID from the failed request headers (x-ms-correlation-request-id), this dramatically speeds up the support investigation.

Prevention & Best Practices

Once your .NET AI app setup is working, keeping it working requires some deliberate habits. The AI SDK ecosystem is still moving quickly, packages that are current today may have significant updates within 60–90 days. Here's how to stay ahead of it.

First, pin your Microsoft.Extensions.AI package versions to minor version ranges, not floating latest. A Version="9.*" reference in your .csproj means you'll automatically pull patch releases (good for security fixes) but won't silently jump to a new minor version with breaking changes. For Microsoft Agent Framework packages specifically, I'd pin to exact versions until you've validated each upgrade in a test environment, the orchestration layer is complex enough that subtle behavior changes aren't always obvious from unit tests alone.

Second, implement health checks for your AI provider connections. A .NET health check that verifies your IChatClient can complete a minimal prompt lets your monitoring catch configuration drift before users hit it:

builder.Services.AddHealthChecks()
    .AddCheck<AiProviderHealthCheck>("ai-provider");

Third, never build directly against a specific provider's SDK types in your application logic. Everything should go through IChatClient and IEmbeddingGenerator<TInput, TEmbedding>. This isn't just good architecture, it means you can switch from Azure OpenAI to GitHub Models to Ollama (for local development and cost control) by changing one DI registration line. I've seen teams who bypassed the abstractions layer spend entire sprints migrating when their provider contract changed.

Fourth, keep your OpenTelemetry configuration active from day one, even in early development. Agent Framework's built-in observability means you get distributed traces automatically, but only if the telemetry pipeline is wired. Retrofitting observability into a running agentic system is significantly harder than including it from the start.

Quick Wins
  • Run dotnet outdated (install via dotnet tool install -g dotnet-outdated-tool) monthly to catch stale Microsoft.Extensions.AI and Agent Framework versions before they accumulate
  • Use DefaultAzureCredential from day one, even in local dev, so there's zero credential-handling code difference between your laptop and production
  • Add DOTNET_ENVIRONMENT=Development to your local environment variables so appsettings.Development.json is loaded automatically without extra code
  • Store your Ollama model pull commands in a setup.sh or setup.ps1 script in the repo so new team members can get a local AI environment running with one command

Frequently Asked Questions

Why should I choose .NET to build AI apps instead of Python?

If your team already ships production software in .NET, the answer is straightforward: you get to keep your entire existing toolchain, Visual Studio, your CI/CD pipelines, your deployment infrastructure, your authentication and logging patterns, and just add AI capabilities on top. You don't need a separate Python microservice that your C# backend has to call over HTTP. The Microsoft.Extensions.AI libraries support the same AI providers Python developers use (OpenAI, Azure OpenAI, Google Gemini, Amazon Bedrock, Ollama) through a unified C# abstraction layer. You also get the .NET performance characteristics, strong typing that catches prompt-related bugs at compile time, and the same dependency injection, configuration, and secret management patterns your team already knows. Python has the larger AI ecosystem right now, but for teams building on ASP.NET Core, Blazor, MAUI, or any other .NET runtime, the integration story with Microsoft.Extensions.AI is genuinely first-class.

What can I actually build with AI and .NET, is it just chatbots?

Not at all, chatbots are just the most visible example. The real opportunity is task automation embedded in your existing .NET applications: automatically labeling the severity of customer support tickets as they come in, generating document summaries for a document management system, doing semantic search over an internal knowledge base using vector embeddings and RAG (retrieval-augmented generation), or building multi-step workflows where an AI agent calls into your existing .NET APIs to complete business processes without human intervention. Computer vision (identifying objects in images), audio generation (synthesized voices for customer interactions), and content classification are all supported through the provider ecosystem that plugs into Microsoft.Extensions.AI. Microsoft Agent Framework specifically opens up the agentic automation space, workflows where multiple specialized AI agents collaborate, hand off tasks, and complete multi-step processes that would have required custom automation code to wire together manually.

What's the difference between Microsoft.Extensions.AI and Microsoft Agent Framework, do I need both?

Microsoft.Extensions.AI is the abstractions layer, it gives you IChatClient, IEmbeddingGenerator, and related interfaces that work the same way regardless of which AI provider is underneath. Think of it as the IDbConnection of AI: the interface is standard, the implementation is provider-specific. Microsoft Agent Framework is built on top of those abstractions and adds higher-level orchestration: multi-agent coordination, sequential and parallel execution patterns, tool calling, group chat, handoff between agents, and the magentic pattern where a lead agent directs others. For a simple single-model chat feature, Microsoft.Extensions.AI alone is enough. The moment you need more than one agent, complex reasoning chains, or enterprise-grade observability over an agentic workflow, Agent Framework is the right choice. You don't need to choose at project start, you can begin with raw IChatClient and graduate to Agent Framework as complexity grows.

Can I run AI models locally with .NET without paying for Azure OpenAI or OpenAI?

Yes, and it's genuinely useful for development and testing. Install Ollama from ollama.com, pull a model like Phi-3 (ollama pull phi3), and Llama 3 (ollama pull llama3), then use Microsoft.Extensions.AI.Ollama to connect your .NET app to it. The IChatClient interface is identical regardless of whether you're talking to Ollama locally or Azure OpenAI in production, so you can develop and test with a local model (zero API cost, works offline, no rate limits) and deploy to Azure OpenAI or another cloud provider by changing one DI registration. The models available through Ollama, Llama, Mistral, Phi-3, and many others, are capable enough for most development use cases. For production, you'll want to evaluate whether the model quality matches your requirements, since local models generally trail the frontier models on complex reasoning tasks.

I'm getting "No service for type IChatClient has been registered", what's wrong?

This runtime exception means your DI container doesn't have a registered implementation for the IChatClient interface. The most common causes: you installed Microsoft.Extensions.AI.Abstractions (the interface-only package) but forgot to add your provider package like Microsoft.Extensions.AI.OpenAI or Microsoft.Extensions.AI.Ollama; or you created the client correctly but registered it as a concrete type rather than as IChatClient. In Program.cs, make sure your registration line explicitly specifies the interface: builder.Services.AddSingleton<IChatClient>(...), not builder.Services.AddSingleton(new OllamaChatClient(...)), which registers the concrete type only. Also verify that your service registration happens before builder.Build() is called, services registered after the app is built won't be visible to the DI container.

How do I build a RAG (retrieval-augmented generation) app with .NET AI?

The .NET AI ecosystem has dedicated packages for each layer of a RAG pipeline. Microsoft.Extensions.DataIngestion handles reading and processing documents, chunking them into pieces that fit model context windows, applying any preprocessing you need. IEmbeddingGenerator<TInput, TEmbedding> (from Microsoft.Extensions.AI) converts text chunks into vector embeddings using your choice of embedding model. Microsoft.Extensions.VectorData.Abstractions provides a unified interface for storing and querying those embeddings across different vector stores, Qdrant, Azure SQL, CosmosDB, MongoDB, ElasticSearch, and more, so you can switch vector store providers without rewriting your retrieval logic. At query time, your app embeds the user's question, finds the most semantically similar document chunks via vector search, and passes those chunks as context to IChatClient.CompleteAsync() along with the original question. Microsoft's official tutorial "Implement RAG using vector search" in the .NET AI docs walks through the full pipeline end to end.

Related Microsoft Fix Guides

H
Sai Kiran Pandrala
Our team includes certified Microsoft engineers, Azure architects, and system administrators with 10+ years of enterprise IT experience. Every guide is written from hands-on troubleshooting, not guesswork. We test every fix before publishing.