ory/hydra · error
failed to generate private key: %s
Error message
failed to generate private key: %s
What it means
NewClientCert always generates a fresh 3072-bit RSA key for the client certificate. If rsa.GenerateKey fails — practically only when the random source fails — the function returns this wrapped error. The failure is environmental: rsa.GenerateKey reads heavily from crypto/rand, so entropy problems surface here first.
Source
Thrown at oryx/tlsx/cert.go:311
return nil, errors.WithStack(err)
}
return &pem.Block{Type: "PRIVATE KEY", Bytes: b}, nil
}
// NewClientCert creates a new client TLS certificate signed by the given CA.
func NewClientCert(CAcert *x509.Certificate, CAkey crypto.PrivateKey, opts ...CertificateOpts) (*tls.Certificate, error) {
if !slices.Contains(CAcert.ExtKeyUsage, x509.ExtKeyUsageClientAuth) {
return nil, errors.Errorf("the CA certificate does not have the client authentication extended key usage (OID 1.3.6.1.5.5.7.3.2) set")
}
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return nil, errors.Errorf("failed to generate serial number: %s", err)
}
key, err := rsa.GenerateKey(rand.Reader, 3072)
if err != nil {
return nil, errors.Errorf("failed to generate private key: %s", err)
}
template := &x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{"Ory GmbH"},
CommonName: "ORY",
},
Issuer: CAcert.Subject,
NotBefore: time.Now().UTC(),
NotAfter: CAcert.NotAfter,
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
BasicConstraintsValid: true,
IsCA: false,
}
for _, opt := range opts {
opt(template)View on GitHub (pinned to 4174065ffb)
Solutions
- Ensure the runtime has a working /dev/urandom and that seccomp policies allow getrandom(2).
- Retry — if the cause is transient entropy exhaustion, subsequent attempts succeed after the kernel pools are seeded.
- Move key generation to a host with a healthy RNG or a hardware entropy source.
Defensive patterns
Strategy: retry
Validate before calling
if f, err := os.Open("/dev/urandom"); err != nil {
// RNG device missing — generation will fail
} else {
f.Close()
} Try / catch
client, err := tlsx.NewClientCert(caCert, caKey)
if err != nil && strings.Contains(err.Error(), "failed to generate private key") {
// rsa.GenerateKey RNG failure: fix random source, then retry
} Prevention
- Ensure the container image includes /dev/urandom and does not strip device nodes.
- Allow getrandom(2) in sandbox syscall filters — RSA keygen draws heavily on crypto/rand.
- Generate keys on a host with adequate entropy or an RNG device (e.g. virtio-rng).
When it happens
Trigger: Calling NewClientCert in an environment where crypto/rand reads fail or stall during the RSA keygen loop — broken /dev/urandom, seccomp-blocked getrandom(2), or a kernel entropy shortage on legacy systems.
Common situations: CI containers with restricted device access; embedded/minimal images missing /dev/urandom; old VMs generating keys immediately after boot before entropy is seeded.
Related errors
- failed to generate serial number: %s
- invalid key size for RSA key, 2048 or more is required
- jwksx: key size must be at least 2048 bit for algorithm "%s"
- failed to create certificate: %s
- failed to encode private key: %s
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/3936895031c55816.
Report an issue: GitHub.