nats-io/nats-server · error
failed to parse cert: %v
Error message
failed to parse cert: %v
What it means
After the CA file, getOCSPIssuer parses each raw certificate in the provided chain with x509.ParseCertificate. A chain entry that is not a valid DER-encoded X.509 certificate aborts startup of the OCSP monitor with this wrapped error.
Source
Thrown at server/ocsp.go:957
var trustedCAs []*x509.Certificate
var certBundle []*x509.Certificate
var err error
// FIXME(tgb): extend if pluggable CA store provider added to NATS (i.e. other than PEM file)
// Non-system default CA trust store passed
if caFile != _EMPTY_ {
trustedCAs, err = parseCertPEM(caFile)
if err != nil {
return nil, fmt.Errorf("failed to parse ca_file: %v", err)
}
}
// Specify bundled intermediate CA store
for _, certBytes := range chain {
cert, err := x509.ParseCertificate(certBytes)
if err != nil {
return nil, fmt.Errorf("failed to parse cert: %v", err)
}
certBundle = append(certBundle, cert)
}
issuer, err = getOCSPIssuerLocally(trustedCAs, certBundle)
if err != nil || issuer == nil {
return nil, fmt.Errorf("no issuers found")
}
if !issuer.IsCA {
return nil, fmt.Errorf("%s invalid ca basic constraints: is not ca", issuer.Subject)
}
return issuer, nil
}
func ocspStatusString(n int) string {
switch n {
case ocsp.Good:View on GitHub (pinned to 3a66a489d2)
Solutions
- Build the chain from tls.ConnectionState().PeerCertificates instead of raw byte slices
- Validate each file's certs with `openssl crl2pkcs7 -nocrl -certfile bundle.pem | openssl pkcs7 -print_certs -noout`
- Remove any non-certificate text (keys, garbage) from the bundle file
Example fix
// before
chain := [][]byte{ rawFileBytes } // not per-cert DER
// after
chain := [][]byte{}
for _, c := range conn.PeerCertificates { chain = append(chain, c.Raw) } Defensive patterns
Strategy: validation
Validate before calling
for i, raw := range chain {
if _, err := x509.ParseCertificate(raw); err != nil {
return fmt.Errorf("chain[%d] is not a valid DER cert: %w", i, err)
}
} Prevention
- Populate chain from tls.ConnectionState().PeerCertificates Raw fields
- Never store non-der bytes in chain slices
- Dump and inspect the chain when debugging OCSP startup
When it happens
Trigger: NewOCSPMonitor called with a chain slice containing bytes that fail x509.ParseCertificate (empty entries, TLS handshake leftovers, malformed DER).
Common situations: Chain bytes harvested incorrectly from tls.ConnectionState (indexing PeerCertificates wrong), or a corrupted/hand-edited bundle file.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unexpected PEM certificate type: %s
- invalid issuer configuration: %w
- invalid chain link
- no available OCSP servers
- unable to extract x509 from certificate
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/fa0e14e24b5bf18f.
Report an issue: GitHub.