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, nil

View on GitHub (pinned to 1c1dc4ed27)

Solutions

  1. Retry `mkcert -uninstall` once the machine is idle (no Windows Update / certutil activity).
  2. Temporarily exclude the mkcert process in AV/EDR policy or coordinate with IT for a cert-store modification window.
  3. Verify the store is readable: `certutil -store ROOT` — if this also fails, the store or profile is damaged; investigate that first.
  4. 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

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


AI-assisted analysis of FiloSottile/mkcert@1c1dc4ed27 (2026-08-15). Data as JSON: /api/errors/f8bccc4e6efc0853. Report an issue: GitHub.