ory/hydra · error

failed to create certificate: %s

Error message

failed to create certificate: %s

What it means

CreateSelfSignedCertificate calls x509.CreateCertificate to sign the template with the provided key. If the Go standard library rejects the operation — most commonly because the key is not a supported RSA/ECDSA private key or the public/private keys do not match — this error wraps the underlying x509 error. It indicates the key argument passed to the function is invalid for certificate creation.

Source

Thrown at oryx/tlsx/cert.go:279

		Issuer: pkix.Name{
			Organization: []string{"ORY GmbH"},
			CommonName:   "ORY",
		},
		NotBefore:             time.Now().UTC(),
		NotAfter:              time.Now().UTC().Add(time.Hour * 24 * 31),
		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
		BasicConstraintsValid: true,
		IsCA:                  true,
		DNSNames:              []string{"localhost"},
	}
	for _, opt := range opts {
		opt(certificate)
	}

	der, err := x509.CreateCertificate(rand.Reader, certificate, certificate, PublicKey(key), key)
	if err != nil {
		return cert, errors.Errorf("failed to create certificate: %s", err)
	}

	cert, err = x509.ParseCertificate(der)
	if err != nil {
		return cert, errors.Errorf("failed to encode private key: %s", err)
	}
	return cert, nil
}

// PEMBlockForKey returns a PEM-encoded block for key.
func PEMBlockForKey(key interface{}) (*pem.Block, error) {
	b, err := x509.MarshalPKCS8PrivateKey(key)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return &pem.Block{Type: "PRIVATE KEY", Bytes: b}, nil
}

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Verify the key is a parsed private key (*rsa.PrivateKey or *ecdsa.PrivateKey) — use PEMBlockForKey/tls helpers or x509.ParsePKCS8PrivateKey to parse PEM first.
  2. Confirm the key type is supported by your Go version (ed25519 requires Go 1.13+).
  3. Ensure the public key embedded in the certificate matches the signing key (the library calls PublicKey(key) for you, so a mismatch usually means the wrong value was passed as key).

Example fix

// before
cert, err := tlsx.CreateSelfSignedCertificate(pemBytes) // raw PEM
// after
key, err := x509.ParsePKCS1PrivateKey(pemBytes)
if err != nil { /* handle */ }
cert, err := tlsx.CreateSelfSignedCertificate(key)
Defensive patterns

Strategy: validation

Validate before calling

switch k := key.(type) {
case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey:
    // ok
default:
    // parse PEM first or reject
}
// also verify the key is the private, not public, half

Type guard

func isSupportedPrivateKey(key interface{}) bool {
    switch key.(type) {
    case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey:
        return true
    default:
        return false
    }
}

Try / catch

cert, err := tlsx.CreateSelfSignedCertificate(key)
if err != nil && strings.Contains(err.Error(), "failed to create certificate") {
    // key invalid: re-parse PEM into a proper private key and retry
}

Prevention

When it happens

Trigger: Passing a key that is not a supported private key type (e.g. an ed25519 key on an old Go version, a *rsa.PublicKey instead of the private key, or a PEM string not yet parsed) into CreateSelfSignedCertificate or GetOrCreateTLSCertificate.

Common situations: Loading a key from a file and passing the PEM bytes instead of a parsed key object; using key algorithms unsupported by the Go version; passing a public key where the private key is required.

Understand the failure class

Related errors


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