{"record":{"id":"42468abdf370cff5","repo":"FiloSottile/mkcert","slug":"invalid-pem-data","errorCode":null,"errorMessage":"invalid PEM data","messagePattern":"invalid PEM data","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"truststore_windows.go","lineNumber":41,"sourceCode":")\n\nvar (\n\tmodcrypt32                           = syscall.NewLazyDLL(\"crypt32.dll\")\n\tprocCertAddEncodedCertificateToStore = modcrypt32.NewProc(\"CertAddEncodedCertificateToStore\")\n\tprocCertCloseStore                   = modcrypt32.NewProc(\"CertCloseStore\")\n\tprocCertDeleteCertificateFromStore   = modcrypt32.NewProc(\"CertDeleteCertificateFromStore\")\n\tprocCertDuplicateCertificateContext  = modcrypt32.NewProc(\"CertDuplicateCertificateContext\")\n\tprocCertEnumCertificatesInStore      = modcrypt32.NewProc(\"CertEnumCertificatesInStore\")\n\tprocCertOpenSystemStoreW             = modcrypt32.NewProc(\"CertOpenSystemStoreW\")\n)\n\nfunc (m *mkcert) installPlatform() bool {\n\t// Load cert\n\tcert, err := ioutil.ReadFile(filepath.Join(m.CAROOT, rootName))\n\tfatalIfErr(err, \"failed to read root certificate\")\n\t// Decode PEM\n\tif certBlock, _ := pem.Decode(cert); certBlock == nil || certBlock.Type != \"CERTIFICATE\" {\n\t\tfatalIfErr(fmt.Errorf(\"invalid PEM data\"), \"decode pem\")\n\t} else {\n\t\tcert = certBlock.Bytes\n\t}\n\t// Open root store\n\tstore, err := openWindowsRootStore()\n\tfatalIfErr(err, \"open root store\")\n\tdefer store.close()\n\t// Add cert\n\tfatalIfErr(store.addCert(cert), \"add cert\")\n\treturn true\n}\n\nfunc (m *mkcert) uninstallPlatform() bool {\n\t// We'll just remove all certs with the same serial number\n\t// Open root store\n\tstore, err := openWindowsRootStore()\n\tfatalIfErr(err, \"open root store\")\n\tdefer store.close()","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/FiloSottile/mkcert/blob/1c1dc4ed27ed5936046b6398d39cab4d657a2d8e/truststore_windows.go#L23-L59","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: corrupt/DER file saved as rootCA.pem\n-----BEGIN TRUSTED CERTIFICATE-----\nMIID... (truncated line, missing footer)\n\n// after: valid PEM produced by regenerating the CA\n// rm \"$CAROOT/rootCA.pem\" \"$CAROOT/rootCA-key.pem\"\n// mkcert -install\n-----BEGIN CERTIFICATE-----\nMIIDvzCCAqegAwIBAgI...full base64...\n-----END CERTIFICATE-----","handlingStrategy":"validation","validationCode":"caroot, err := exec.Command(\"mkcert\", \"-CAROOT\").Output()\nif err == nil {\n    p := filepath.Join(strings.TrimSpace(string(caroot)), \"rootCA.pem\")\n    if data, rerr := os.ReadFile(p); rerr == nil {\n        if block, _ := pem.Decode(data); block == nil || block.Type != \"CERTIFICATE\" {\n            log.Fatalf(\"%s is not a valid CERTIFICATE PEM; regenerate the CA\", p)\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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`."],"tags":["mkcert","windows","pem","certificate","ca-root","local-development"],"backgroundTag":null,"analyzedSha":"1c1dc4ed27ed5936046b6398d39cab4d657a2d8e","analyzedAt":"2026-08-15T09:28:09.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}