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

  1. Build the chain from tls.ConnectionState().PeerCertificates instead of raw byte slices
  2. Validate each file's certs with `openssl crl2pkcs7 -nocrl -certfile bundle.pem | openssl pkcs7 -print_certs -noout`
  3. 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

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

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/fa0e14e24b5bf18f. Report an issue: GitHub.