The page loaded, but the browser warns about the certificate
Port 4443 is the usual stand-in for 443, so whatever you're running expects HTTPS. Browsers only trust certificates signed by an authority they know. A self-signed certificate, or one for the wrong name, gets a warning page. Match the error code you see:
| Error | What it means and what to do |
|---|---|
NET::ERR_CERT_AUTHORITY_INVALIDSEC_ERROR_UNKNOWN_ISSUER |
The certificate is self-signed or from an authority your system doesn't trust. Create a locally trusted one with mkcert (below). |
NET::ERR_CERT_COMMON_NAME_INVALIDSSL_ERROR_BAD_CERT_DOMAIN |
The certificate doesn't list the name you browsed to. A cert for 127.0.0.1 won't cover localhost, and the reverse. Reissue it with every name you use. |
ERR_SSL_PROTOCOL_ERRORSSL_ERROR_RX_RECORD_TOO_LONG |
The server is speaking plain HTTP on a port you reached with HTTPS. Use the http:// link above, or turn on TLS in the server. |
NET::ERR_CERT_DATE_INVALID |
The certificate expired or isn't valid yet. Reissue it, and check the system clock if it's a fresh cert. |
ERR_CONNECTION_REFUSED |
Nothing is listening on 4443. See the server isn't answering. |
On a Chrome warning page with no "Proceed" option, typing thisisunsafe bypasses it for that site. It works, but it teaches you to click through certificate warnings. Fixing trust takes two minutes.
Make a certificate your machine trusts
mkcert creates a private certificate authority on your computer, adds it to your system and browser trust stores, and issues certificates from it.
- Install it:
brew install mkcerton macOS,choco install mkcertorwinget install FiloSottile.mkcerton Windows, or your Linux package manager. - Create and trust the local authority. This runs once per machine.
mkcert -install - Issue a certificate covering every name you browse to.
This writesmkcert localhost 127.0.0.1 ::1localhost+2.pemandlocalhost+2-key.pemin the current folder. - Point your server at those two files and restart it.
Keep the authority's key private: mkcert -CAROOT shows where it lives. Anyone with that file can create certificates your machine will trust.
Firefox still complains
Firefox keeps its own trust store. mkcert fills it automatically when certutil (from NSS tools) is installed. Otherwise, set security.enterprise_roots.enabled to true in about:config so Firefox uses the system store.
The browser is fine, but code and tools reject the certificate
Many runtimes ship their own list of trusted authorities and ignore the system store. Point them at the mkcert root:
Node.js
export NODE_EXTRA_CA_CERTS="$(mkcert -CAROOT)/rootCA.pem"
This adds to Node's built-in list rather than replacing it. Set it before starting the process.
Python (requests, httpx, urllib)
pip install truststore
import truststore
truststore.inject_into_ssl()
truststore makes Python use the operating system's trust store, which mkcert already updated. Setting REQUESTS_CA_BUNDLE or SSL_CERT_FILE to rootCA.pem also works, but it replaces the default bundle, so public HTTPS sites will then fail.
curl
curl --cacert "$(mkcert -CAROOT)/rootCA.pem" https://localhost:4443/
.NET / ASP.NET Core
dotnet dev-certs https --trust
This creates and trusts the ASP.NET Core development certificate, which Kestrel uses by default. You don't need mkcert unless you want one authority across all your tools.
Java
keytool -importcert -cacerts -alias mkcert-local \
-file "$(mkcert -CAROOT)/rootCA.pem"
You'll be prompted for the trust store password (the default is changeit). Each JDK installation has its own store, so repeat this for each one you use.
Vite
// vite.config.js
import fs from 'node:fs'
export default {
server: {
port: 4443,
https: {
key: fs.readFileSync('localhost+2-key.pem'),
cert: fs.readFileSync('localhost+2.pem'),
},
},
}
The server isn't answering
Check whether anything is listening on 4443, and which process it is.
macOS and Linux
lsof -nP -iTCP:4443 -sTCP:LISTEN
Windows PowerShell
Get-NetTCPConnection -LocalPort 4443 -State Listen |
Select-Object LocalAddress, OwningProcess,
@{n='Process'; e={ (Get-Process -Id $_.OwningProcess).ProcessName }}
If nothing shows up, the server isn't running or it chose another port, so check its startup output. If it's listening only on ::1 or only on 127.0.0.1, try the other address directly: https://127.0.0.1:4443/. Containers need the port published, for example docker run -p 4443:4443.
Stop the browser from sending you here again
In Chrome, Edge, Brave, or Firefox, type localhost in the address bar, arrow down to the localhost4443.com suggestion, and press Shift + Delete. On a Mac laptop keyboard, use Shift + Fn + Delete.
Safari has no shortcut for removing a single suggestion. Remove localhost4443.com from History instead. From then on, type the full https://localhost:4443 once and Safari will suggest that instead.