{"record":{"id":"089d6b6c9740ac83","repo":"FiloSottile/mkcert","slug":"failed-adding-cert-v","errorCode":null,"errorMessage":"failed adding cert: %v","messagePattern":"failed adding cert: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"truststore_windows.go","lineNumber":104,"sourceCode":"\t\treturn nil\n\t}\n\treturn fmt.Errorf(\"failed to close windows root store: %v\", err)\n}\n\nfunc (w windowsRootStore) addCert(cert []byte) error {\n\t// TODO: ok to always overwrite?\n\tret, _, err := procCertAddEncodedCertificateToStore.Call(\n\t\tuintptr(w), // HCERTSTORE hCertStore\n\t\tuintptr(syscall.X509_ASN_ENCODING|syscall.PKCS_7_ASN_ENCODING), // DWORD dwCertEncodingType\n\t\tuintptr(unsafe.Pointer(&cert[0])),                              // const BYTE *pbCertEncoded\n\t\tuintptr(len(cert)),                                             // DWORD cbCertEncoded\n\t\t3,                                                              // DWORD dwAddDisposition (CERT_STORE_ADD_REPLACE_EXISTING is 3)\n\t\t0,                                                              // PCCERT_CONTEXT *ppCertContext\n\t)\n\tif ret != 0 {\n\t\treturn nil\n\t}\n\treturn fmt.Errorf(\"failed adding cert: %v\", err)\n}\n\nfunc (w windowsRootStore) deleteCertsWithSerial(serial *big.Int) (bool, error) {\n\t// Go over each, deleting the ones we find\n\tvar cert *syscall.CertContext\n\tdeletedAny := false\n\tfor {\n\t\t// Next enum\n\t\tcertPtr, _, err := procCertEnumCertificatesInStore.Call(uintptr(w), uintptr(unsafe.Pointer(cert)))\n\t\tif cert = (*syscall.CertContext)(unsafe.Pointer(certPtr)); cert == nil {\n\t\t\tif errno, ok := err.(syscall.Errno); ok && errno == 0x80092004 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn deletedAny, fmt.Errorf(\"failed enumerating certs: %v\", err)\n\t\t}\n\t\t// Parse cert\n\t\tcertBytes := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:cert.Length]\n\t\tparsedCert, err := x509.ParseCertificate(certBytes)","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/FiloSottile/mkcert/blob/1c1dc4ed27ed5936046b6398d39cab4d657a2d8e/truststore_windows.go#L86-L122","documentation":"addCert calls CertAddEncodedCertificateToStore with CERT_STORE_ADD_REPLACE_EXISTING on the ROOT store; a zero return means the API rejected the DER bytes. The input is the DER payload decoded from rootCA.pem, so common causes are a malformed/expired/unparseable certificate, or an access-denied on the protected ROOT store despite it being open.","triggerScenarios":"`mkcert -install` where rootCA.pem decodes as PEM but its DER payload is corrupt or truncated (pem.Decode succeeded, the bytes after are not a valid X.509); a certificate Windows refuses (e.g. weak algorithm like a signature Windows' policy disables); insufficient privileges or policy blocking writes to the trusted root store.","commonSituations":"Editing/syncing tools that strip characters but leave a syntactically valid PEM envelope; CAs generated with algorithms disallowed by Windows crypto policy; enterprise policies that forbid adding self-signed roots; CA file regenerated mid-install by a concurrent mkcert run.","solutions":["Validate the DER independently: `openssl x509 -in rootCA.pem -noout -text` to confirm it parses and inspect algorithm/expiry.","If the CA is corrupt, back up and delete CAROOT, then rerun `mkcert -install` to generate a fresh one.","Run from an elevated terminal to rule out access-denied on the ROOT store.","If a group policy restricts root additions, use the approved distribution mechanism (GPO/MDM) to deploy mkcert's CA instead."],"exampleFix":"# before\nmkcert -install   # failed adding cert: ... \n\n# after: verify then regenerate\nopenssl x509 -in \"$(mkcert -CAROOT)/rootCA.pem\" -noout -text\nrm \"$(mkcert -CAROOT)/rootCA.pem\" \"$(mkcert -CAROOT)/rootCA-key.pem\"\nmkcert -install","handlingStrategy":"validation","validationCode":"block, _ := pem.Decode(pemBytes)\nif block == nil {\n    return errors.New(\"not PEM\")\n}\nif _, err := x509.ParseCertificate(block.Bytes); err != nil {\n    return fmt.Errorf(\"DER does not parse as X.509: %w\", err)\n}\n// only call install after both checks pass","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate rootCA.pem with `openssl x509 -noout -text` before every scripted install.","Generate CAs with current algorithms (RSA-2048+/ECDSA P-256+) that Windows policy accepts.","Run installs elevated so access-denied is ruled out before blaming the cert bytes.","Do not regenerate CAROOT concurrently with an install."],"tags":["mkcert","windows","crypt32","certificate","root-store","installation"],"backgroundTag":null,"analyzedSha":"1c1dc4ed27ed5936046b6398d39cab4d657a2d8e","analyzedAt":"2026-08-15T09:28:09.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}