caddyserver/caddy · error
can't parse the given certificate: %s
Error message
can't parse the given certificate: %s
What it means
VerifyClientCertificate takes rawCerts[0] (the client's leaf certificate as sent on the wire) and parses it with x509.ParseCertificate; a parse failure is wrapped as 'can't parse the given certificate'. The bytes came from the TLS peer, so this indicates the peer sent malformed certificate data rather than a config problem.
Source
Thrown at modules/caddytls/connpolicy.go:1038
if !ok {
return fmt.Errorf("leaf module '%s' is not a leaf certificate loader", vMod)
}
l.LeafCertificateLoadersRaw = append(
l.LeafCertificateLoadersRaw,
caddyconfig.JSONModuleObject(vMod, "loader", modName, nil),
)
}
return nil
}
func (l LeafCertClientAuth) VerifyClientCertificate(rawCerts [][]byte, _ [][]*x509.Certificate) error {
if len(rawCerts) == 0 {
return fmt.Errorf("no client certificate provided")
}
remoteLeafCert, err := x509.ParseCertificate(rawCerts[0])
if err != nil {
return fmt.Errorf("can't parse the given certificate: %s", err.Error())
}
if slices.ContainsFunc(l.trustedLeafCerts, remoteLeafCert.Equal) {
return nil
}
return fmt.Errorf("client leaf certificate failed validation")
}
// PublicKeyAlgorithm is a JSON-unmarshalable wrapper type.
type PublicKeyAlgorithm x509.PublicKeyAlgorithm
// UnmarshalJSON satisfies json.Unmarshaler.
func (a *PublicKeyAlgorithm) UnmarshalJSON(b []byte) error {
algoStr := strings.ToLower(strings.Trim(string(b), `"`))
algo, ok := publicKeyAlgorithms[algoStr]
if !ok {
return fmt.Errorf("unrecognized public key algorithm: %s (expected one of %v)",View on GitHub (pinned to 50e54ee279)
Solutions
- Reproduce with a known-good client (openssl s_client -connect host:443 -cert client.pem -key client.key) to confirm the server config is fine
- Inspect what the peer sends: capture with tcpdump and decode the Certificate handshake message
- Fix or update the offending client's certificate serialization
- If behind a proxy/terminator, verify it forwards the original client certificate bytes unchanged
Defensive patterns
Strategy: try-catch
Try / catch
// If you build custom verifiers on top of x509.ParseCertificate
if _, err := x509.ParseCertificate(rawCerts[0]); err != nil {
// peer sent malformed certificate bytes; reject and log peer identity (IP/SNI)
return fmt.Errorf("peer sent unparseable certificate: %w", err)
} Prevention
- Do not hand-roll TLS certificate serialization; use crypto/tls
- Validate certs at issue time in your CA/PKI tooling
- Treat recurring parse failures from one peer as tampering or a broken client
When it happens
Trigger: A TLS client presenting a corrupted, truncated, or non-X.509 certificate; hand-rolled TLS clients that put arbitrary bytes in the Certificate message; middleboxes/terminators that mangle the chain.
Common situations: Custom TLS implementations or load tests (e.g. raw TLS scripts) sending garbage; proxies that re-encode certificates badly; extremely rare with mainstream clients — treat as peer-side fault or tampering.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- no client certificate provided
- no permission module configured; certificates not allowed ex
- source %T returned a nil certificate
- dropping connection
- no server TLS configuration available for ClientHello: %+v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/3c1f71d6508a0cfc.
Report an issue: GitHub.