azure-cosmos-dotnet-v3: How to use V3 CosmosClient with Emulator while ignoring SSL errors?
Describe the bug Impossible to connect CosmosClient to Emulator while trying to ignore SSL certificates.
I already searched this repo and the web to find some information about how to ignore the SSL error if we try to connect to the emulator. All I could find was some hints on how to solve these problems on V2 DocumentClient (like #42), but nothing for V3 CosmosClient.
I dig through the public interface of the class, their options, etc. and the only maybe promising I could find was the Collection<RequestHandler> CustomHandlers
. So I wrote my own handler (see below), added it to the options
new CosmosClient(EndPoint, Key, new CosmosClientOptions { CustomHandlers = { new IgnoringSSLErrorsRequestHandler() } });
and guess what, it won’t be called (so I also don’t know if the implementation is correct or does really work).
Expected behavior
Some code example on how it is possible to instantiate an CosmosClient
that will ignore SSL errors.
Actual behavior Nothing is available to work around this problem, except importing the certificate to the windows certificate store, but we need some solution in pure code.
Environment summary SDK Version: 3.6.0 OS Version: Windows
Additional context
internal class IgnoringSSLErrorsRequestHandler : RequestHandler
{
private readonly HttpClient _httpClient;
public IgnoringSSLErrorsRequestHandler()
{
var messageHandler = new HttpClientHandler { ServerCertificateCustomValidationCallback = (req, cert, chain, errors) => true };
_httpClient = new HttpClient(messageHandler);
}
public override async Task<ResponseMessage> SendAsync(RequestMessage request, CancellationToken cancellationToken)
{
var httpRequest = new HttpRequestMessage
{
Method = request.Method,
RequestUri = request.RequestUri,
};
foreach (var headerKey in request.Headers.AllKeys())
{
httpRequest.Headers.Add(headerKey, request.Headers[headerKey]);
}
foreach (var kvp in request.Properties)
{
httpRequest.Properties.Add(kvp);
}
var response = await _httpClient.SendAsync(httpRequest, cancellationToken);
return new ResponseMessage(response.StatusCode, request)
{
Content = await response.Content.ReadAsStreamAsync()
};
}
}
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 1
- Comments: 28 (9 by maintainers)
I gave up trying to work around the ssl issue, and I am currently trying to get a custom cosmos docker image to work.
Honestly, this has been the biggest waste of dev time in my entire life. The MS Cosmos team should add a
no SSL
config option; just like the rest of the tools we use! You dont have to run mongo, mysql, etc etc locally with a cert… you can if you want to, but it isn’t mandatory. That’s the part that annoys me most; treating developers with kid gloves!Another vote for an “insecure” dev mode. I have spent far too long trying to get this to work in docker across several languages.
I’d really like to NOT import a certificate somewhere. I’d like to use the emulator locally without validating the certificate in my test code. That should really be possible, especially for testing.
Why not add an option to run the emulator with HTTP connection? Similar to asp.net core where you have both HTTP and HTTPS. I wonder actually why HTTPS is used for the emulator. Someone was going to run the emulator on prod environment?
I might be wrong, but having HTTP option will solve all problems with accessing emulator from other machines or containers. And also this option will allow use exactly same code for dev and prod environments.
@olivermue This is a similar scenario to when you run an HTTPS application in a local server with a self-signed certificate. If you want to connect to that HTTPS application from other machine or instance, you need to trust that certificate by adding it to your list of trusted ones because it is a self-signed certificate.
The Emulator has its own certificate, that when you run locally in the same machine, it is automatically trusted because it is the same machine. This works out of the box.
If you want to access the Emulator from a different machine or environment (if you use Docker or a VM), you need to trust the certificate in order to establish an HTTPS connection, this is a basic HTTPS usage scenario for any secure application.
As @j82w said, adding programmatic ways to disable SSL only leads to production security issues when that code is accidentally pushed to production. The “hassle” of correctly trusting the certificate in a testing environment is rather better than the potential security breach of pushing code to production, don’t you think?
I totally agree with the developers above, just because it is the “Right Way” doesn’t mean that we should do “Rocket Science” to perform a simple stupid connection with the emulator that is ONLY NEEDED for dev mode. This is very frustrating and people that are working with Docker and CosmosDB cannot do simple development at the moment of writing this post.
Either write the correct docs pages on Microsoft website with a step-by-step guide or give a possibility to disable SSL when developing with docker.
BTW: I have also opened a ticket for this issue #1551
To echo @erjok sentiment, I think we (as MSFT) should give developers the benefit of the doubt of being smart enough to not disable SSL for production environment and provide a way to ignore SSL errors.
Currently I’m dealing with the issue of trying to get Remote Development containers work with Cosmos Db Emulator. This is because my MSFT team develops in Windows but wants to move towards containers.
We previously supported overriding the SSL in v2’s DocumentClient as seen in the documentation here.
However, using v2 does not work for me due to implementation of v2 not supporting host.docker.internal URIs as seen by the issue here, which is the only clean way to connect from my container to the host machine that hosts Cosmos Db Emulator because MSFT hasn’t been able to move the emulator into a linux container since June 2018 because of constant delays.
I also understand/appreciate intended sentiment on installing the local development certificate because we consider this the “right way”. However, even installing the cert locally as @j82w suggested does not work as .NET Core relies on OpenSSL and OpenSSL says the generated cert’s public key for CosmosDbEmulator (RSA 1024 bit), is too weak. I manually downgraded the openssl configuration, but alas, the alternative subject name obviously wouldn’t match, since I’ll never be trying to hit the host machine through localhost from my Linux container.
So just to trust the cert locally in my container, am I supposed to generate my own cert that’s valid for Cosmos Db Emulator with DNS of host.docker.internal, export the pfx on windows, convert the pfx to a crt on my linux container, trust the crt on my Linux container, downgrade openssl config SECLEVEL in my container on bootup, and then distribute that to the rest of my team because this is the “right way”? I did get the SSL somewhat working via the GenCert argument provided by Cosmos Db Emulator, but I’m dreading scripting the first half and getting the second half working with the mounted volume during Dockerfile.
I’m still having issues getting the actual client to work because of an “Endpoint not reachable. Refresh cache and retry” warning because the v3 client for some reason resolves https://host.docker.internal:8081 to https://127.0.0.1:8081/ which it can’t hit because obviously 127.0.0.1:8081 does not exist in the container.

I will probably give up this approach, and figure out a way to grab my host machine’s external ip from my container (which is such a niche need I have no idea where to start) as per this reply and abandon v3 cosmosclient for documentclient.
Meanwhile, I would prefer if there was an alternative solution that is a bit cleaner and developer friendly so I didn’t have to jump through so many hoops to get to this conclusion.
@DaleyKD
Sorry for not seeing your replies. I have the same dev scenario as you. I already unblocked my team on this and have it working for multiple members but am waiting for the cleaner solution still as well.
While the Cosmos team does the good work to circumvent SSL, my steps should unblock you. The point of the /GenCert flag is to generate the cert with host.docker.internal as part of the SAN. Then the Fail on ssl mismatch flag makes sure the emulator doesn’t generate a new one that doesnt have host.docker.internal as part of the cert SAN. I’m providing the exact scripts I use below.
I would recommend manually cleaning the certs if running through my steps above again as you might have some leftover certs generated from before, or running my new script below that does that for you. When you start the cosmos emulator via the command I supplied, you can click the browser and verify its using the cert you expect by hitting the lock button and checking the cert generated and is being used as expected

Here is my setup script that I use for my team to both install and output the cert in the current directory. NOTE: I now output directly in source directory instead of depending on mounted directory like I did before because the bash script will not be able to access the mounted directory during dockerfile build. This was not an issue with Visual Studio Code containers since they can run commands after the dockerfile is built, but is an issue for more vanilla docker setups that I needed to support.
Then I slightly modified my bash script in the same folder to run as a step during the dockerfile
Then for Visual Studio Code containers simply add the bash script as part of the postCreateCommand in devcontainer.json. For vanilla dockerfiles add the script to run by copying and running it. Of course pay attention that the scripts folder is same level or below your Dockerfile context. For Visual Studio Code Remote Development Containers:
For Dockerfile:
Then the run script is the same, but just a bit nicer to people that don’t want to install in default location for some reason and restarts process if it’s already running.
Then overall steps are the same for the user. Run setup script the first time, then rebuild docker container calling the bash script that has the .pfx file, then make sure cosmos is running via the run script before the service starts up.
I hope that helps meanwhile.
I also have the same use case as @whung1 and there does exist disableSSLVerification key in other cosmos-db language SDKs. I was able to use the disableSSLVerification for python and it was neat and something which I was looking for C# as well. While searching , I got to know that similar thing exists in azure-cosmos-js as well. It’s way better to have a disableSSLVerification feature added to avoid the hassle of extra automation as suggested above and increase adoption. Do consider adding disableSSLVerification feature in your coming sprints, because clearly from the thread above, it’s not just folks at Microsoft ( @whung1 and me), but others too who are looking forward to it.
Thanks for the help @ealsur
I was able to get
host.docker.internal
working with/AllowNetworkAccess
. This makes it so we don’t have to do ipconfig on host machine to manually replace any containerized env variable endpoints for development containers./AllowNetworkAccess
to work withhost.docker.internal
based on my experience there beforeSteps:
.\Microsoft.Azure.Cosmos.Emulator.exe /GenCert=host.docker.internal
to generate and install a cert that allowshost.docker.internal
to be trusted..\Microsoft.Azure.Cosmos.Emulator.exe /FailOnSslCertificateNameMismatch /allownetworkaccess /Key=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==
https://host.docker.internal:8081
As you can see, installing the certificate is not trivial (steps 1-4, where step 4 is especially inconvenient). Thus hopefully as per this ticket, we can ignore SSL errors in the future and then steps 5-6 are trivial to get a nice development container working irregardless of where the emulator is hosted (on host machine, on another linux container within the same docker network).
Again, I think the PR #1441 linked by j82w worked on by ealsur might be able give this workaround by adding clienthandler to the httpclient from the httpfactory example.
@j82w - Man, that would BE AWESOME.
However, when I try to use the HttpClientFactory func in CosmosClientOptions, it appears to never hit the breakpoint of trying to get an HttpClient.
Startup.cs
Index.cshtml.cs
When we get to
.CreateDatabaseIfNotExistsAsync
, the breakpoint onHttpClientFactory
is never hit, nor is the one in myHttpClientHandler
for the SSL verification.This is making me feel like I’m obviously missing something.
EDIT: Forgot to mention that as soon as we try to call
.CreateDatabaseIfNotExistsAsync
, we get the good ol’AuthenticationException: The remote certificate is invalid according to the validation procedure.
I see nothing in the callstack that refers toGatewayStoreModel,
but I do see:which is before a new
GatewayStoreModel
is instantiated. It’s like theDocumentClient
doesn’t want to use theHttpClientFactory
option.It sounds like I need to carefully analyze @whung1 's answer.
Our dev scenario:
The SSL issue is stopping us because of localhost vs host.docker.internal in the SAN/CN/subject/whatever.
Additional comment…
Ideally, we’ll be using EF Core Cosmos DB provider. However, in version 3.1, it doesn’t support
IDictionary<string, object>
, so I’ve got a strange hybrid where I use aDbContext
, but then insert/update/select using the underlyingCosmosClient
.When thinking about how to allow us to get past this SSL issue (without the huge ‘create a special cert for Docker, blah blah’), is it possible for you to coordinate with EF Core and find a way to allow us to bypass SSL issues using the
DbContext
?I’ve fought the emulator a LOT lately, and it’s greatly frustrated me, simply because of this local dev issue. We get it to work for a while, but then the emulator decides to regenerate the old style key.
Haha. I joined our current cloud product team in October with no knowledge of Docker, Cosmos, Azure, Azure Storage, etc. I cursed Docker for weeks until I wrote that .ps1. I think getting that .ps1 to do what I needed it to do took a full Planning Increment week and some of the next sprint. A big portion of that was learning NGINX and what it took to mirror our Azure Cloud setup.
Once I learned all of this, next thing I know, it’s not so bad. And that includes getting this SSL issue for Cosmos DB resolved. All the work (especially SSL certs) is done thru the .ps1 instead of in each docker image.
To be fair, we haven’t fully stood it up in local dev yet. We should be getting that working on Monday.
@DaleyKD thank you so much for your detailed response!
Getting cosmos up and running locally for development, and in CI for our functional testing, has been a real nightmare. This is something that should have taken hours, not days! 😦
@joshystuart - For me, I use the .ps1 as part of the development cycle. It has assisted us with managing the docker-compose and Docker containers. It helps:
It manages:
But, in regards to this topic, it also:
So, I just added the necessary SSL certs from Cosmos DB to be a part of the “Initial Setup” steps described above.
How funny! I had started working on my .ps1 (I’ve got one we use to help manage our local docker images/container), and this is the function I wrote:
We already had OpenSSL installed for previous reasons.
Then, I was simply going to modify my docker-compose to mount the .crt.