FiloSottile/mkcert · error
failed enumerating certs: %v
Error message
failed enumerating certs: %v
What it means
During uninstall, mkcert loops CertEnumCertificatesInStore over the ROOT store; the expected loop exit is the CRYPT_E_NOT_FOUND errno 0x80092004 when enumeration finishes. Any other error while the returned context is NULL produces this message. In practice the store handle is bad (already closed) or an external actor (AV, concurrent cert-store modification) disrupted enumeration.
Source
Thrown at truststore_windows.go:118
)
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)
// We'll just ignore parse failures for now
if err == nil && parsedCert.SerialNumber != nil && parsedCert.SerialNumber.Cmp(serial) == 0 {
// Duplicate the context so it doesn't stop the enum when we delete it
dupCertPtr, _, err := procCertDuplicateCertificateContext.Call(uintptr(unsafe.Pointer(cert)))
if dupCertPtr == 0 {
return deletedAny, fmt.Errorf("failed duplicating context: %v", err)
}
if ret, _, err := procCertDeleteCertificateFromStore.Call(dupCertPtr); ret == 0 {
return deletedAny, fmt.Errorf("failed deleting certificate: %v", err)
}
deletedAny = true
}
}
return deletedAny, nilView on GitHub (pinned to 1c1dc4ed27)
Solutions
- Retry `mkcert -uninstall` once the machine is idle (no Windows Update / certutil activity).
- Temporarily exclude the mkcert process in AV/EDR policy or coordinate with IT for a cert-store modification window.
- Verify the store is readable: `certutil -store ROOT` — if this also fails, the store or profile is damaged; investigate that first.
- As a manual fallback, delete the 'mkcert' entry via certmgr.msc or `certutil -delstore ROOT <serial>`.
Example fix
# manual removal matching mkcert's serial-based delete certutil -store ROOT | findstr /i mkcert certutil -delstore ROOT <serial-from-output>
Defensive patterns
Strategy: retry
Validate before calling
if out, err := exec.Command("certutil", "-store", "ROOT").CombinedOutput(); err != nil {
log.Fatalf("ROOT store unreadable; fix store before uninstall: %s", out)
} Prevention
- Schedule uninstalls when Windows Update / certutil maintenance is not running.
- Exclude mkcert from overzealous AV interception where policy allows.
- Retry once after transient store errors before investigating deeper.
- Keep `certutil -delstore ROOT <serial>` as a known manual fallback.
When it happens
Trigger: `mkcert -uninstall` while another process concurrently modifies the ROOT store; the store handle being invalidated (service restart); AV/EDR software intercepting certificate-store enumeration; memory corruption of the CertContext pointer chain in unusual environments.
Common situations: CI jobs running mkcert uninstall concurrently with Windows Update or certutil store maintenance; security software on corporate laptops; running mkcert under Wine/Windows-compatibility layers where crypt32 semantics differ.
Related errors
- failed deleting certificate: %v
- no certs found
- failed to open windows root store: %v
- failed duplicating context: %v
- failed to close windows root store: %v
AI-assisted analysis of FiloSottile/mkcert@1c1dc4ed27 (2026-08-15).
Data as JSON: /api/errors/f8bccc4e6efc0853.
Report an issue: GitHub.