ory/hydra · error
the CA certificate does not have the client authentication…
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.
Solutions
- Re-create the CA with the client-auth EKU: pass an option that sets ExtKeyUsage to include x509.ExtKeyUsageClientAuth.
- If you cannot re-issue the CA, provision a separate CA that is allowed for client authentication.
- 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
- Create CAs intended for mTLS with ExtKeyUsage including x509.ExtKeyUsageClientAuth.
- Validate loaded CA certificates' ExtKeyUsage before using them to sign client certs.
- Keep separate CAs for server-auth and client-auth roles in your PKI.
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
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- failed to create certificate
- failed to encode private key
- unable to load X509 key pair from files
- unable to load X509 key pair
- can not serve request over insecure http
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/02a30ee30a1f5ccb.
Report an issue: GitHub.
Appendix: 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)