FiloSottile/mkcert · error
failed adding cert: %v
Error message
failed adding cert: %v
What it means
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.
Source
Thrown at truststore_windows.go:104
return nil
}
return fmt.Errorf("failed to close windows root store: %v", err)
}
func (w windowsRootStore) addCert(cert []byte) error {
// TODO: ok to always overwrite?
ret, _, err := procCertAddEncodedCertificateToStore.Call(
uintptr(w), // HCERTSTORE hCertStore
uintptr(syscall.X509_ASN_ENCODING|syscall.PKCS_7_ASN_ENCODING), // DWORD dwCertEncodingType
uintptr(unsafe.Pointer(&cert[0])), // const BYTE *pbCertEncoded
uintptr(len(cert)), // DWORD cbCertEncoded
3, // DWORD dwAddDisposition (CERT_STORE_ADD_REPLACE_EXISTING is 3)
0, // PCCERT_CONTEXT *ppCertContext
)
if ret != 0 {
return nil
}
return fmt.Errorf("failed adding cert: %v", err)
}
func (w windowsRootStore) deleteCertsWithSerial(serial *big.Int) (bool, error) {
// Go over each, deleting the ones we find
var cert *syscall.CertContext
deletedAny := false
for {
// Next enum
certPtr, _, err := procCertEnumCertificatesInStore.Call(uintptr(w), uintptr(unsafe.Pointer(cert)))
if cert = (*syscall.CertContext)(unsafe.Pointer(certPtr)); cert == nil {
if errno, ok := err.(syscall.Errno); ok && errno == 0x80092004 {
break
}
return deletedAny, fmt.Errorf("failed enumerating certs: %v", err)
}
// Parse cert
certBytes := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:cert.Length]
parsedCert, err := x509.ParseCertificate(certBytes)View on GitHub (pinned to 1c1dc4ed27)
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.
Example fix
# before mkcert -install # failed adding cert: ... # after: verify then regenerate openssl x509 -in "$(mkcert -CAROOT)/rootCA.pem" -noout -text rm "$(mkcert -CAROOT)/rootCA.pem" "$(mkcert -CAROOT)/rootCA-key.pem" mkcert -install
Defensive patterns
Strategy: validation
Validate before calling
block, _ := pem.Decode(pemBytes)
if block == nil {
return errors.New("not PEM")
}
if _, err := x509.ParseCertificate(block.Bytes); err != nil {
return fmt.Errorf("DER does not parse as X.509: %w", err)
}
// only call install after both checks pass Prevention
- 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.
When it happens
Trigger: `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.
Common situations: 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.
Related errors
- invalid PEM data
- failed to open windows root store: %v
- failed to close windows root store: %v
- failed enumerating certs: %v
- failed duplicating context: %v
AI-assisted analysis of FiloSottile/mkcert@1c1dc4ed27 (2026-08-15).
Data as JSON: /api/errors/089d6b6c9740ac83.
Report an issue: GitHub.