Errors¶
Every error the package produces, verbatim, with what causes it and what to change.
All of them are github.com/cockroachdb/errors values, so errors.Is/errors.As
reach the wrapped cause and %+v prints a stack trace.
They all surface while you are building a config. None of them can happen mid-flight on a live listener.
loading TLS certificate: …¶
From Pair.Certificate, and so from ServerConfig and ApplyTo too. The wrapped
cause comes straight from crypto/tls.LoadX509KeyPair, and covers more than a missing
file:
| Wrapped cause | Meaning |
|---|---|
open …: no such file or directory |
Wrong path, or a relative path resolved against a different working directory |
open …: permission denied |
The process cannot read the file — check ownership and mode, which bites most often on the key |
tls: failed to find any PEM data in certificate input |
cert is not PEM — DER, a PKCS#12 bundle, or an empty file |
tls: failed to find any PEM data in key input |
Same, for key |
tls: private key does not match public key |
cert and key are from different key pairs |
unknown client_auth "…" (valid: "request", "verify-if-given", "require-verify")¶
Pair.ClientAuth is set to something the package does not recognise. The comparison
is exact: lower-case, hyphenated, no surrounding whitespace. Underscores, capitals and
the crypto/tls constant names (RequireAndVerifyClientCert) are all rejected.
The rejection is deliberate. An unrecognised mode could only be handled by falling back to something, and every fallback is either a silent downgrade or a surprise — so it fails instead. See Why an unknown mode is an error rather than a fallback.
This error fires even when the config you are merging into already has its own client-certificate policy and the pair's would have been ignored.
client_auth "…" requires client_cas to verify against¶
require-verify and verify-if-given both verify a client certificate against a CA
pool, and no CA files were given. Set client_cas, or drop to request if you only
want the certificate collected rather than checked.
request never produces this error — it does not verify anything.
reading CA file "…": …¶
reading CA file "/etc/certs/client-ca.pem": open /etc/certs/client-ca.pem: no such file or directory
From CertPool, and so from ClientConfig and from any pair with client_cas set.
The file could not be read at all.
no certificates found in "…"¶
The file was read but x509.CertPool.AppendCertsFromPEM found nothing usable in it.
Usual causes: a DER file with a .pem name, a private key where a certificate was
meant, a truncated download, or a file of PEM blocks that are not CERTIFICATE.
This is an error rather than a shrug on purpose: an empty trust store that verifies nothing looks exactly like a working one until something tries to connect.
nil TLS config¶
Pair.ApplyTo(nil). Pass a config to merge into — &cryptotls.Config{} if you want
an unhardened one, or tls.DefaultConfig() for the hardened base (at which point
ServerConfig is the shorter spelling).
Handshake failures, which are not this package's errors¶
A rejected connection produces a crypto/tls error at the listener, not an error from
this package. The common ones under mTLS:
| Server log | Cause |
|---|---|
tls: client didn't provide a certificate |
require-verify and the client sent none |
tls: failed to verify certificate: x509: certificate signed by unknown authority |
The client certificate does not chain to any CA in client_cas |
tls: failed to verify certificate: x509: certificate specifies an incompatible key usage |
The client certificate carries an extended key usage that is not clientAuth — usually serverAuth copied from the server certificate. A certificate with no EKU at all is accepted |
tls: client offered only unsupported versions: [301] |
The peer cannot do TLS 1.2 |
remote error: tls: bad certificate |
The peer rejected your certificate — usually missing CA trust on their side |
tls: client didn't provide a certificate is also what you get from a Go client
holding a certificate from the wrong CA. The server advertises which CAs it will
accept, and a Go client silently withholds a certificate that does not match, so the
mismatch reaches you as an absence rather than as a verification failure. A client
that sends regardless — curl, or a Go client using GetClientCertificate — produces
the unknown authority line instead. Both mean the same thing: the client
certificate does not chain to anything in client_cas.
On the client side, x509: certificate signed by unknown authority from a Go client
that used ClientConfig with CA files usually means the opposite of what it looks
like: the server's certificate is fine and publicly trusted, but passing CA files
replaced the system roots. See
Private-CA trust replaces the system roots.