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
- Inspect the file: print %CAROOT%\rootCA.pem and confirm it starts with '-----BEGIN CERTIFICATE-----' and ends with '-----END CERTIFICATE-----'.
- 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.
- If the file is DER, convert it to PEM: `openssl x509 -inform der -in rootCA.pem -out rootCA-fixed.pem` and replace the file.
- 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
- Never hand-edit rootCA.pem; treat the whole CAROOT directory as opaque.
- Pin CAROOT to a stable dedicated directory outside sync/scratch folders.
- Back up CAROOT (rootCA.pem + rootCA-key.pem together) instead of recreating the PEM from copies of the cert text.
- Before scripting `mkcert -install`, verify rootCA.pem parses with `openssl x509 -noout -in rootCA.pem`.
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
- failed adding cert: %v
- no certs found
- failed to open windows root store: %v
- failed to close windows root store: %v
- failed enumerating certs: %v
AI-assisted analysis of FiloSottile/mkcert@1c1dc4ed27 (2026-08-15).
Data as JSON: /api/errors/42468abdf370cff5.
Report an issue: GitHub.