FiloSottile/mkcert · error

invalid PEM data

Error message

invalid PEM data

What it means

mkcert throws this while installing its local CA into the Windows root store: it reads rootCA.pem from the CAROOT directory and pem.Decode() either returns no block or a block whose type is not "CERTIFICATE". In practice this means the file at %CAROOT%/rootCA.pem is missing, empty, truncated, or not PEM at all. Note the surrounding ioutil.ReadFile error would surface separately, so this specific message means the file exists but is not a decodable CERTIFICATE PEM.

Source

Thrown at truststore_windows.go:41

)

var (
	modcrypt32                           = syscall.NewLazyDLL("crypt32.dll")
	procCertAddEncodedCertificateToStore = modcrypt32.NewProc("CertAddEncodedCertificateToStore")
	procCertCloseStore                   = modcrypt32.NewProc("CertCloseStore")
	procCertDeleteCertificateFromStore   = modcrypt32.NewProc("CertDeleteCertificateFromStore")
	procCertDuplicateCertificateContext  = modcrypt32.NewProc("CertDuplicateCertificateContext")
	procCertEnumCertificatesInStore      = modcrypt32.NewProc("CertEnumCertificatesInStore")
	procCertOpenSystemStoreW             = modcrypt32.NewProc("CertOpenSystemStoreW")
)

func (m *mkcert) installPlatform() bool {
	// Load cert
	cert, err := ioutil.ReadFile(filepath.Join(m.CAROOT, rootName))
	fatalIfErr(err, "failed to read root certificate")
	// Decode PEM
	if certBlock, _ := pem.Decode(cert); certBlock == nil || certBlock.Type != "CERTIFICATE" {
		fatalIfErr(fmt.Errorf("invalid PEM data"), "decode pem")
	} else {
		cert = certBlock.Bytes
	}
	// Open root store
	store, err := openWindowsRootStore()
	fatalIfErr(err, "open root store")
	defer store.close()
	// Add cert
	fatalIfErr(store.addCert(cert), "add cert")
	return true
}

func (m *mkcert) uninstallPlatform() bool {
	// We'll just remove all certs with the same serial number
	// Open root store
	store, err := openWindowsRootStore()
	fatalIfErr(err, "open root store")
	defer store.close()

View on GitHub (pinned to 1c1dc4ed27)

Solutions

  1. Inspect the file: print %CAROOT%\rootCA.pem and confirm it starts with '-----BEGIN CERTIFICATE-----' and ends with '-----END CERTIFICATE-----'.
  2. If the PEM is unrecoverable, regenerate the CA: delete rootCA.pem and rootCA-key.pem (back them up first; all previously trusted certs become invalid), then run `mkcert -install` again.
  3. If the file is DER, convert it to PEM: `openssl x509 -inform der -in rootCA.pem -out rootCA-fixed.pem` and replace the file.
  4. Verify CAROOT points where you expect with `mkcert -CAROOT` and fix the env var if it targets the wrong directory.

Example fix

// before: corrupt/DER file saved as rootCA.pem
-----BEGIN TRUSTED CERTIFICATE-----
MIID... (truncated line, missing footer)

// after: valid PEM produced by regenerating the CA
// rm "$CAROOT/rootCA.pem" "$CAROOT/rootCA-key.pem"
// mkcert -install
-----BEGIN CERTIFICATE-----
MIIDvzCCAqegAwIBAgI...full base64...
-----END CERTIFICATE-----
Defensive patterns

Strategy: validation

Validate before calling

caroot, err := exec.Command("mkcert", "-CAROOT").Output()
if err == nil {
    p := filepath.Join(strings.TrimSpace(string(caroot)), "rootCA.pem")
    if data, rerr := os.ReadFile(p); rerr == nil {
        if block, _ := pem.Decode(data); block == nil || block.Type != "CERTIFICATE" {
            log.Fatalf("%s is not a valid CERTIFICATE PEM; regenerate the CA", p)
        }
    }
}

Prevention

When it happens

Trigger: Calling `mkcert -install` (installPlatform) when CAROOT/rootCA.pem is corrupt, zero-byte, contains only a PRIVATE KEY block, was hand-edited, or is a DER-encoded certificate saved with a .pem extension. Also when CAROOT points at a wrong directory that happens to contain a file named rootCA.pem.

Common situations: Manually copying or moving the CAROOT folder and mangling the file; CAROOT env var pointing to a stale or partial directory; a previous mkcert run interrupted mid-write; converting the CA to DER/base64-without-headers; syncing CAROOT through a tool that truncated long lines.

Related errors


AI-assisted analysis of FiloSottile/mkcert@1c1dc4ed27 (2026-08-15). Data as JSON: /api/errors/42468abdf370cff5. Report an issue: GitHub.