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

  1. Ensure the runtime has a working /dev/urandom and that seccomp policies allow getrandom(2).
  2. Retry — if the cause is transient entropy exhaustion, subsequent attempts succeed after the kernel pools are seeded.
  3. 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

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


AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03). Data as JSON: /api/errors/3936895031c55816. Report an issue: GitHub.