ory/hydra · error

the CA certificate does not have the client authentication e

Error message

the CA certificate does not have the client authentication extended key usage (OID 1.3.6.1.5.5.7.3.2) set

What it means

NewClientCert signs a client certificate using the provided CA. Before doing any work it checks that the CA certificate declares ExtKeyUsageClientAuth (OID 1.3.6.1.5.5.7.3.2). If the CA was created without the client-auth extended key usage, signing a client cert from it would yield a certificate peers reject, so the function fails fast with this error. It is a configuration problem with the CA certificate, not with the client key.

Source

Thrown at oryx/tlsx/cert.go:301

	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
}

// 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",
		},

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Re-create the CA with the client-auth EKU: pass an option that sets ExtKeyUsage to include x509.ExtKeyUsageClientAuth.
  2. If you cannot re-issue the CA, provision a separate CA that is allowed for client authentication.
  3. Verify the loaded CA with cert.CheckSignature/cert.ExtKeyUsage before calling NewClientCert.

Example fix

// before
caCert, _ := tlsx.CreateSelfSignedCertificate(caKey) // no EKU opts
client, err := tlsx.NewClientCert(caCert, caKey)
// after
caCert, _ := tlsx.CreateSelfSignedCertificate(caKey, func(c *x509.Certificate) {
    c.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}
    c.IsCA = true
})
client, err := tlsx.NewClientCert(caCert, caKey)
Defensive patterns

Strategy: validation

Validate before calling

func caSupportsClientAuth(caCert *x509.Certificate) bool {
    return slices.Contains(caCert.ExtKeyUsage, x509.ExtKeyUsageClientAuth)
}
// call before NewClientCert

Type guard

func isClientAuthCA(cert *x509.Certificate) bool {
    return cert != nil && slices.Contains(cert.ExtKeyUsage, x509.ExtKeyUsageClientAuth)
}

Try / catch

client, err := tlsx.NewClientCert(caCert, caKey)
if err != nil && strings.Contains(err.Error(), "client authentication extended key usage") {
    // re-issue the CA with ExtKeyUsageClientAuth before retrying
}

Prevention

When it happens

Trigger: Calling NewClientCert with a CA certificate generated without the ClientAuth extended key usage option (e.g. created via CreateSelfSignedCertificate with default opts, which sets server auth, or with ExtKeyUsage opts that omitted x509.ExtKeyUsageClientAuth).

Common situations: Reusing a server-only TLS CA to mint client certificates for mTLS; loading a CA from an external PKI that was provisioned for server authentication only; forgetting to pass the ExtKeyUsage option when creating the CA.

Understand the failure class

Related errors


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