AppConfiguration Emulator authentication not compatible with App Configuration SDK
- Dominant language
- C#
- Stars
- 6.3k
- Forks
- 991
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 196
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues
### Describe the bug
I'm trying to use the new App Configuration emulator, and it would appear the App Configuration SDK does not like the auth setup the Emulator establishes.
I setup the emulator, as docs suggest, then I try to seed the app configuration with some config, but when calling something like `.SetConfigurationSettingAsync` on the *ConfigurationClient*, it throws with a 401 response.
If I just use my own HttpClient and hit the emulator endpoints directly using the App Configuration SDK, (i.e. I don't send any auth headers), it works fine.
### Expected Behavior
I should be able to use the App Configuration SDK with the emulator-provided connectionString and not experience 401 responses.
### Steps To Reproduce
The code:
``` csharp
// AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureContainerAppEnvironment("aspire-env");
var config = builder.AddAzureAppConfiguration("config");
if (builder.ExecutionContext.IsRunMode)
{
config.RunAsEmulator(emulator => emulator.WithDataBindMount("../AppHostData/AppConfig"));
builder.Eventing.Subscribe(config.Resource, async (@event, ct) =>
await AppConfigSeeder.SeedAfterEmulatorStartsAsync(@event.Resource, ct));
}
```
``` csharp
// AppConfigSeeder.cs
public static async Task SeedAfterEmulatorStartsAsync(IResource resource, CancellationToken cancellationToken)
{
if (resource is not IResourceWithConnectionString configResource)
{
return;
}
var connectionString = await configResource.GetConnectionStringAsync(cancellationToken);
if (string.IsNullOrEmpty(connectionString))
{
Console.WriteLine("⚠️ Could not get App Configuration endpoint - skipping auto-seed.");
return;
}
Console.WriteLine("\n🌱 Auto-seeding App Configuration emulator.\n");
await SeedEmulatorAsync(connectionString, cancellationToken);
}
private static async Task SeedEmulatorAsync(string connectionString, CancellationToken cancellationToken = default)
{
try
{
Console.WriteLine($"Connection string: {connectionString}");
var configSettings = GetConfigurationSettings(); // This is just a function that returns a list of config settings I'm trying to seed any. The actual settings themselves are irrelevant here.
var client = new ConfigurationClient(connectionString);
Console.WriteLine("\nSeeding configuration settings...");
foreach (var setting in configSettings)
{
try
{
await client.SetConfigurationSettingAsync(setting, cancellationToken: cancellationToken);
}
catch (RequestFailedException ex) when (ex.Status == (int)HttpStatusCode.Unauthorized)
{
Console.WriteLine($" ❌ 401 Unauthorized when setting '{setting.Key}'"); // <--- This is where we end up
throw;
}
}
}
catch (RequestFailedException ex) when (ex.Status != (int)HttpStatusCode.NotFound)
{
Console.WriteLine("\n❌ Failed to seed App Configuration (RequestFailedException):");
Console.WriteLine($" Status: {ex.Status}");
Console.WriteLine($" Message: {ex.Message}");
throw;
}
catch (Exception ex) when (ex is not JsonException)
{
Console.WriteLine($"\n❌ Failed to seed App Configuration ({ex.GetType().Name}):");
Console.WriteLine($" Message: {ex.Message}");
if (ex.InnerException != null)
{
Console.WriteLine($" Inner: {ex.InnerException.GetType().Name}: {ex.InnerException.Message}");
}
throw;
}
}
```
### Exceptions (if any)
The error I get back in the 401 response has:
For troubleshooting information, see https://aka.ms/azsdk/net/appconfiguration/troubleshoot.
Status: 401 (Unauthorized)
Headers:
Date: Thu, 12 Feb 2026 20:55:23 GMT
Server: Kestrel
WWW-Authenticate: HMAC-SHA256 error="forbidden", error_description="Authentication scheme disabled",Bearer,Anonymous
x-ms-request-id: b8da24c7-c82a-46f8-ad9e-37ef4b9ddb39
x-ms-client-request-id: 342fa90e-ea02-42bf-9a9a-1208f67bf30f
x-ms-correlation-request-id: b8da24c7-c82a-46f8-ad9e-37ef4b9ddb39
Content-Length: 0
Using GHC, it caught that the example project doesn't have/use Anonymous=True in the connectionString, so I tried removing that, and I still get a 401 response, but the error says it's an invalid token.
### .NET Version info
10.0.103
### Anything else?
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.