kgretzky/evilginx2 · critical
private key generation failed
Error message
private key generation failed
What it means
generateCertificates (called from NewCertDb) throws this when crypto/rand rsa.GenerateKey(2048) fails during regeneration of the CA private key. The previous key was already determined to be missing or corrupted, so this is a last-resort failure. It deliberately discards the underlying error detail and returns a fixed message.
Source
Thrown at core/certdb.go:94
}
return email
}
func (o *CertDb) generateCertificates() error {
var key *rsa.PrivateKey
pkey, err := ioutil.ReadFile(filepath.Join(o.cache_dir, "private.key"))
if err != nil {
pkey, err = ioutil.ReadFile(filepath.Join(o.cache_dir, "ca.key"))
}
if err != nil {
// private key corrupted or not found, recreate and delete all public certificates
os.RemoveAll(filepath.Join(o.cache_dir, "*"))
key, err = rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return fmt.Errorf("private key generation failed")
}
pkey = pem.EncodeToMemory(&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(key),
})
err = ioutil.WriteFile(filepath.Join(o.cache_dir, "ca.key"), pkey, 0600)
if err != nil {
return err
}
} else {
block, _ := pem.Decode(pkey)
if block == nil {
return fmt.Errorf("private key is corrupted")
}
key, err = x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return errView on GitHub (pinned to 4c0988a1d9)
Solutions
- Verify /dev/urandom is available and getrandom(2) is not blocked by the container/seccomp profile, then restart
- Clear the cache_dir so a fresh, valid key can be written and re-run
- Check disk permissions/space for writing ca.key (0600) in cache_dir
- Update Go / the library if running on a platform with known crypto/rand issues
Example fix
// before os.RemoveAll(filepath.Join(o.cache_dir, "*")) // glob does not expand; cache may persist // after os.RemoveAll(o.cache_dir) os.MkdirAll(o.cache_dir, 0700)
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check the environment before NewCertDb
f, err := os.Open("/dev/urandom")
if err != nil { log.Fatal("no entropy source available") }
f.Close()
if st, err := os.Stat(cacheDir); err != nil || !st.IsDir() { os.MkdirAll(cacheDir, 0700) } Try / catch
db, err := NewCertDb(cacheDir, "")
if err != nil {
if err.Error() == "private key generation failed" {
// entropy/RNG issue: check /dev/urandom, seccomp, then retry
log.Fatal("cannot generate RSA key: check entropy source and container policy")
}
log.Fatal(err)
} Prevention
- Ensure /dev/urandom is accessible in containers; avoid seccomp rules blocking getrandom
- Keep cache_dir writable with 0700 permissions
- Monitor for repeated cache corruption that triggers the regenerate path
- Pin a maintained Go version and library release
When it happens
Trigger: NewCertDb cannot read the cached ca.key, deletes the cache (os.RemoveAll of the cache dir), and then rsa.GenerateKey fails — practically only when the system CSPRNG (rand.Reader) fails or is unavailable (e.g. broken /dev/urandom in a stripped container).
Common situations: Containers/seccomp sandboxes blocking getrandom(); extremely constrained environments; corrupted cache_dir contents triggering the recreate path where a latent RNG problem then surfaces.
Related errors
- private key is corrupted
- failed to get TLS certificate for: %s:%d error: %s
- failed to list certificates in directory '%s': %v
- failed to list certificate directory '%s': %v
AI-assisted analysis of kgretzky/evilginx2@4c0988a1d9 (2026-09-05).
Data as JSON: /api/errors/476fba71f18363df.
Report an issue: GitHub.