CosmosDB preview emulator: HTTPS endpoint switch ignores certificate availability, breaks CI
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 72/100
Research direction
Start in AzureCosmosDBExtensions.cs, then trace SubscribeHttpsEndpointsUpdate and HttpsCertificateExecutionConfigurationGatherer.GatherAsync to compare endpoint selection with certificate configuration. Reproduce the DistributedApplicationTestingBuilder scenario without a trusted developer certificate. Done means the preview emulator and resolved connection string use compatible HTTP or HTTPS settings on CI.
Written by the indexing model from the issue text.
Description
Description
After upgrading from Aspire.Hosting.Azure.CosmosDB 13.1.x to 13.2.0, integration tests that use RunAsPreviewEmulator started failing on CI (Azure DevOps) with SSL errors, while working fine on developer machines.
The root cause is a logic mismatch introduced in #14663 (267e787) — the endpoint scheme is switched to HTTPS unconditionally, but the certificate environment variables are only configured when a dev cert is actually available.
Root Cause
In AzureCosmosDBExtensions.cs, RunAsPreviewEmulator does two things:
1. Adds an HttpsCertificateAnnotation with UseDeveloperCertificate = true:
emulatorSurrogateBuilder.WithHttpsDeveloperCertificate(password: ...);
Since AzureCosmosDBEmulatorResource.Annotations delegates to the inner AzureCosmosDBResource, this annotation ends up on the main resource.
2. Subscribes to BeforeStartEvent to switch the endpoint to HTTPS:
builder.SubscribeHttpsEndpointsUpdate(ctx =>
{
builder.WithEndpoint("emulator", ep => { ep.UriScheme = "https"; });
});
Inside SubscribeHttpsEndpointsUpdate, the check is:
else if (annotation.UseDeveloperCertificate.GetValueOrDefault(developerCertificateService.UseForHttps) || ...)
{
addHttps = true;
}
Because UseDeveloperCertificate is explicitly true (not null), GetValueOrDefault returns true regardless of developerCertificateService.UseForHttps. The endpoint always switches to HTTPS.
Meanwhile, the certificate env var setter (HttpsCertificateExecutionConfigurationGatherer.GatherAsync) does the right thing:
if (certificate is null)
{
return; // No dev cert → exit early, no PROTOCOL/CERT_PATH/CERT_SECRET set
}
So on CI (no trusted dev cert):
SubscribeHttpsEndpointsUpdate→ endpoint becomeshttps://GatherAsync→ no cert found → exits early → noPROTOCOL=httpsenv var- Emulator starts with HTTP
- Connection string resolves to
AccountEndpoint=https://host:port(viaEndpointProperty.Url) - Aspire's internal
CosmosClient.ReadAccountAsync()inOnResourceReadytries HTTPS against an HTTP server →HttpRequestException: The SSL connection could not be established/Cannot determine the frame size or a corrupted frame was received
On dev machines it works because the dev cert exists, so both the endpoint switch and the env var configuration happen together.
Steps to Reproduce
- Create an Aspire AppHost with a CosmosDB preview emulator:
var cosmosDb = builder.AddAzureCosmosDB("cosmos");
cosmosDb.RunAsPreviewEmulator(emulator =>
{
emulator.WithDataExplorer();
});
- Create an integration test using
DistributedApplicationTestingBuilder:
var builder = await DistributedApplicationTestingBuilder
.CreateAsync<Projects.MyAppHost>([], (options, _) =>
{
options.AllowUnsecuredTransport = true;
});
var app = await builder.BuildAsync();
await app.StartAsync();
// This will timeout on CI — OnResourceReady fails with SSL error
await app.ResourceNotifications.WaitForResourceHealthyAsync("cosmos", cts.Token);
- Run on a CI agent that has no trusted ASP.NET Core developer certificate (standard Azure DevOps / GitHub Actions Linux agent).
Expected: Emulator starts with HTTP, endpoint uses HTTP, tests pass.
Actual: Endpoint switches to HTTPS, emulator stays HTTP, SSL handshake fails.
Suggested Fix
In WithHttpsDeveloperCertificate, set UseDeveloperCertificate = null instead of true:
var annotation = new HttpsCertificateAnnotation
{
UseDeveloperCertificate = null, // was: true
Password = password?.Resource,
};
This way, SubscribeHttpsEndpointsUpdate falls back to developerCertificateService.UseForHttps — which properly checks whether a cert actually exists — and the endpoint only switches to HTTPS when the full HTTPS chain can actually work.
Alternatively, SubscribeHttpsEndpointsUpdate could be changed to verify cert availability before switching the scheme, not just check the annotation's intent.
Workaround
For anyone hitting this in the meantime — in the AppHost, after RunAsPreviewEmulator, remove the cert config callbacks and force the endpoint back to HTTP for the testing environment:
if (builder.Environment.EnvironmentName == "Testing")
{
foreach (var annotation in cosmosDb.Resource.Annotations.ToList())
{
var typeName = annotation.GetType().Name;
if (typeName.Contains("HttpsCertificateConfiguration") ||
typeName.Contains("CertificateTrust"))
{
cosmosDb.Resource.Annotations.Remove(annotation);
}
}
builder.Eventing.Subscribe<BeforeStartEvent>((@event, _) =>
{
cosmosDb.WithEndpoint("emulator", e => e.UriScheme = "http");
return Task.CompletedTask;
});
}
Environment
- Aspire.Hosting.Azure.CosmosDB: 13.2.0
- .NET SDK: 10.0
- CI: Azure DevOps (Linux agent, no trusted ASP.NET Core dev cert)
- Emulator image tag:
vnext-EN20260227(also reproducible with defaultvnext-preview)
- Dominant language
- C#
- Stars
- 6.3k
- Forks
- 992
- Avg merge
- 2d 16h
- Merged PRs (30d)
- 176
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from microsoft/aspire
-
ci-failure-cause test-failure
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Difficulty 1/5 Under an hour Newbie friendliness 92/100
-
agentic-workflows needs-area-label
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
-
area-app-model
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
area-integrations triage:bot-seen
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
All issues in microsoft/aspire
Similar issues
-
type/automation type/tech-debt
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
t/bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
area:auth FE mvp P3
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
klasolsson81/jobbliggaren#1788 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
OrchardCMS/OrchardCore#19919 · 2 comments ·