# MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT

## TL;DR
Firefox refuses the connection because the certificate is self-signed: it was not issued by any authority Firefox trusts, so it proves nothing about who runs the server. For anything real, get a proper certificate from a trusted or internal CA. For local development, use mkcert to create a locally trusted CA instead of raw self-signed certs. A manual exception is only acceptable for throwaway testing, never for anything carrying real credentials.

```text
MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT
```

## Use this when
- Firefox blocks an internal tool, dashboard, or device admin page
- Your dev server's HTTPS setup triggers this in Firefox but nowhere else
- A security review flags self-signed certs in non-production environments
- You are deciding between an internal CA and per-host self-signed certs

## Not for this skill when
- The cert is expired (different error)
- The hostname does not match the cert
- The site is HSTS-pinned (no exception path exists there anyway)

## Steps
1. Decide whether the cert should be self-signed at all. Public or team-used services should never be: get a certificate from a public CA or your organization's internal CA. That is the actual fix for anything beyond your own laptop.
   Expected: the service presents a chain Firefox trusts, and the error disappears in every browser.

2. For local development, switch to mkcert. It creates a local CA, installs it into the trust stores, and issues properly-formed certs for your dev names:
   ```bash
   mkcert -install
   mkcert example.test
   ```
   Expected: Firefox trusts the dev cert with no exceptions, and you stop minting raw self-signed certs.

3. For throwaway testing only, use the manual exception. In Firefox: Advanced, then accept the risk and add the exception. Understand what you just did: you told Firefox to trust this specific cert with no verification.
   Expected: the page loads under a temporary exception. Never do this for a host that handles real logins or real data.

4. For internal tools a whole team uses, distribute trust properly. Publish your internal CA certificate with install docs, or put the tool behind a TLS-terminating proxy that already has a proper cert. Per-host self-signed certs do not scale and train everyone to click through warnings.
   Expected: every team member reaches the tool with no warnings and no exceptions.

### Variant: SEC_ERROR_UNKNOWN_ISSUER
Firefox's sibling error: the cert chains to an unknown CA rather than being self-signed. Same family of fixes: install the CA properly or get a proper cert.

### Variant: self-signed on printers and IoT admin pages
Device vendors ship self-signed certs because they cannot know your network. For a printer on your LAN, a targeted exception is the pragmatic answer. For anything reachable beyond the LAN, front it with a proxy that has a real cert.

### Variant: certificate exception not sticking
Exceptions are per Firefox profile. A new profile, a container reset, or policy-managed Firefox wipes them. If you keep re-adding exceptions, that is a sign to fix the cert properly.

### Variant: HSTS site with a self-signed cert
HSTS removes the exception path entirely: Firefox will not let you click through. The only fix is a valid certificate.

## Why this happens
A self-signed certificate is just an assertion: anyone can mint one claiming any name, with no third party vouching for it. Browsers trust certificates because a CA verified the owner's identity before signing. With no CA in the picture, Firefox has nothing to verify against, so it fails closed instead of guessing.

## Edge cases and pitfalls
- Clicking through the warning trains the exact habit attackers exploit. Reserve exceptions for hosts you fully control on networks you trust.
- Firefox uses its own certificate store, separate from the OS. A CA installed at the OS level may still need adding in Firefox's certificate manager.
- Self-signed certs in automated test environments break every new runner until someone clicks through. mkcert or an internal CA in the base image fixes it permanently.
- An exception added for a hostname stays even if the cert changes, depending on settings. Re-verify the fingerprint if the device was reset or reimaged.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_giuJ0sbiT_1Q8XJIvtyh_w
