Local HTTPS and CORS: Pointing a Browser Frontend at a Mockoon Server
Quick answer: When a browser frontend talks to a local Mockoon server, the two things that break first are TLS and CORS, and they are separate problems. Enable HTTPS in Mockoon and make the browser trust the local certificate, then add the CORS headers that allow the frontend's origin to call it. Solving TLS without the CORS headers still leaves the browser blocking the request, and adding CORS over plain HTTP fails when the frontend itself is served securely.
Why the browser is so strict
A browser enforces two independent policies that a tool like curl simply does not. First, it only trusts certificates from known authorities, so a self-signed local certificate produces a security warning and a failed fetch. Second, the same-origin policy blocks a script from reading a response from a different origin unless that response explicitly grants permission. Because a local frontend usually runs on one port and Mockoon on another, the two are different origins even on localhost, which triggers the CORS check.
| Problem | Symptom | Fix |
|---|---|---|
| Untrusted certificate | NET::ERR_CERT_AUTHORITY_INVALID | Trust the local cert |
| Missing CORS headers | Blocked by CORS policy | Allow the frontend origin |
| Wrong allowed method or header | Preflight fails | List method and custom headers |
| HTTP vs HTTPS mismatch | Mixed content warning | Secure both sides |
Enabling HTTPS and trusting the cert
Turn on TLS in Mockoon and point it at a local certificate. For development, generate a certificate for localhost and add it to the system trust store so the browser accepts it without a warning. The exact generation can be done with a local tool that writes a certificate and key in a folder you keep out of version control.
# Generate a local certificate for localhost
openssl req -x509 -newkey rsa:2048 -nodes \
-keyout localhost-key.pem \
-out localhost-cert.pem \
-days 365 \
-subj "/CN=localhost" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
Once the certificate is trusted, point the frontend at https://localhost:<port>. Clicking through a browser warning works for a quick check but is not a reliable setup, because the warning can suppress other behavior and is easy to forget on a new machine.
Adding the CORS headers
Mockoon can return CORS headers on its responses, including the preflight OPTIONS request. The headers must name the frontend origin, the methods the app uses, and any custom headers it sends, such as an authorization header.
Access-Control-Allow-Origin: https://localhost:5173
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 600
Remember that the browser sends an OPTIONS preflight before a request with a custom header, so Mockoon must answer that method correctly with a 204 and the same CORS headers. If the preflight fails, the actual request never leaves the browser.
Credentials and the wildcard trap
A common mistake is combining Access-Control-Allow-Origin: * with credentials. The browser forbids that combination, so when the frontend sends cookies or authorization, the allowed origin must be explicit and Access-Control-Allow-Credentials must be true. Echoing the specific request origin is the practical pattern for local development, as long as you keep that behavior confined to the mock and never carry it into a production default.
Verifying the two layers independently
Debug methodically rather than changing headers at random. First confirm TLS by opening the mock URL directly and seeing a trusted response with no warning, then test the preflight with a direct request and confirm the CORS headers, and finally run the actual fetch from the frontend. Separating the layers tells you whether a failure is a certificate problem or a permission problem, which look similar in the console but have different fixes.
How an agent mishandles it
An agent that sees a blocked request often adds a wildcard origin and calls it solved, which breaks when credentials are involved, or it disables TLS verification rather than trusting the certificate. Ask it to keep an explicit origin and a genuinely trusted local cert. If the agent only handles GET and forgets OPTIONS, the preflight will fail; require the full set of methods and headers so the browser can complete the handshake.
A repeatable local setup script
Because both TLS and CORS have to be right, a small setup script makes the configuration reproducible for the whole team rather than something each person configures by hand. Generate the certificate, confirm the trust step, and keep a mock configuration that already carries the explicit origin and preflight headers. Documenting the one manual step, adding the certificate to the trust store, keeps the rest automated.
#!/usr/bin/env bash
set -euo pipefail
# Generate the local certificate if it does not exist
if [ ! -f localhost-cert.pem ]; then
openssl req -x509 -newkey rsa:2048 -nodes \
-keyout localhost-key.pem -out localhost-cert.pem -days 365 \
-subj "/CN=localhost" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
fi
# Trust it (macOS), then start the mock with HTTPS enabled
sudo security add-trusted-cert -d -r trustRoot \
-k /Library/Keychains/System.keychain localhost-cert.pem
echo "start Mockoon with TLS enabled and the CORS env headers"
With the certificate trusted and the preflight returning the right headers, the frontend behaves against the mock the same way it will against a real secure API, which is the point of doing the extra setup rather than clicking through warnings.
Frequently asked questions
Why are localhost and my frontend considered different origins?
Because the origin includes the port, so a frontend on one port and Mockoon on another are different origins even on the same host, which triggers the CORS check.
Can I just use a wildcard CORS origin?
Not when the request includes credentials or cookies, because the browser rejects a wildcard origin combined with Allow-Credentials. Use an explicit origin for an authenticated frontend.
Do I need to handle OPTIONS separately?
Yes. The browser sends a preflight OPTIONS before a request with custom headers or non-simple methods, so Mockoon must return the CORS headers on that response.
Is clicking through the certificate warning enough?
For a quick test perhaps, but trusting the local certificate properly is more reliable and avoids the warning on every new machine or browser profile.
This is part of the Powerduck vs Mockoon: OpenAPI Mock Servers — start there for the full comparison of running mock servers for local development.