Skip to content
ecdsa.com
Go crypto/x509Go

Error message

x509: certificate specifies an incompatible key usage

Also printed as

  • tls: failed to verify certificate: x509: certificate specifies an incompatible key usage

TLS clients add the "tls: failed to verify certificate: " prefix; Go servers verifying client certificates log "http: TLS handshake error from <addr>: tls: failed to verify certificate: x509: certificate specifies an incompatible key usage".

Go crypto/x509 — CertificateInvalidError (IncompatibleUsage): extendedKeyUsage does not allow this role

What it means

The chain is trusted, but the certificate's extendedKeyUsage (or that of an intermediate, which Go also checks) does not allow the role it is used for: a server certificate without serverAuth, or a client certificate without clientAuth in mutual TLS. Go enforces EKU strictly; some other TLS stacks are more lenient, so the same certificate may work elsewhere.

Why it happens

How to fix it

  1. 1.

    Read the extendedKeyUsage of each certificate

    Check the leaf and every intermediate; the purpose you need must be allowed along the whole path.

    bash
    # Leaf and intermediates: which purposes do they allow?
    openssl x509 -in server.pem -noout -ext extendedKeyUsage,keyUsage
    #   TLS Web Server Authentication = serverAuth, TLS Web Client Authentication = clientAuth
  2. 2.

    Reissue with the correct EKU

    serverAuth for server certificates, clientAuth for client certificates (both if one certificate really must serve both roles).

    bash
    # Server certificates need serverAuth; for mutual TLS client certificates need clientAuth
    openssl req -new -key server.key -out server.csr -subj "/CN=api.example.com" \
      -addext "subjectAltName=DNS:api.example.com" -addext "extendedKeyUsage=serverAuth"
  3. 3.

    Mutual TLS: issue client certificates with clientAuth

    Go servers with RequireAndVerifyClientCert check the client certificate's EKU for clientAuth.

    go
    // Go server verifying client certificates: they need clientAuth (or no EKU at all)
    cfg := &tls.Config{
    	ClientAuth: tls.RequireAndVerifyClientCert,
    	ClientCAs:  clientCAPool,
    }

Related errors

Browse the full signature error database