nats-io/nats-server · error
invalid ocsp ca configuration
Error message
invalid ocsp ca configuration
What it means
Returned by getOCSPIssuerLocally when the supplied certificate bundle is empty, so there is no leaf certificate at position 0 to find an issuer for. Despite the message wording, the actual fault is an empty/missing certificate bundle in the OCSP CA configuration, not a malformed CA per se; the TLS/OCSP setup paths (e.g. when reading cert files for OCSP monitoring) depend on that bundle being non-empty.
Source
Thrown at server/ocsp.go:906
}
pemBytes = append(pemBytes, block.Bytes...)
}
return x509.ParseCertificates(pemBytes)
}
// getOCSPIssuerLocally determines a leaf's issuer from locally configured certificates
func getOCSPIssuerLocally(trustedCAs []*x509.Certificate, certBundle []*x509.Certificate) (*x509.Certificate, error) {
var vOpts x509.VerifyOptions
var leaf *x509.Certificate
trustedCAPool := x509.NewCertPool()
// Require Leaf as first cert in bundle
if len(certBundle) > 0 {
leaf = certBundle[0]
} else {
return nil, fmt.Errorf("invalid ocsp ca configuration")
}
// Allow Issuer to be configured as second cert in bundle
if len(certBundle) > 1 {
// The operator may have misconfigured the cert bundle
issuerCandidate := certBundle[1]
err := issuerCandidate.CheckSignature(leaf.SignatureAlgorithm, leaf.RawTBSCertificate, leaf.Signature)
if err != nil {
return nil, fmt.Errorf("invalid issuer configuration: %w", err)
} else {
return issuerCandidate, nil
}
}
// Operator did not provide the Leaf Issuer in cert bundle second position
// so we will attempt to create at least one ordered verified chain from the
// trusted CA pool.
View on GitHub (pinned to 3a66a489d2)
Solutions
- Verify the TLS cert_file loads correctly and yields a non-empty bundle
- Ensure the leaf certificate is listed first in the cert file
- Re-test with a known-good leaf-first fullchain file
Example fix
// before (cert file empty or issuer-only)
# nats.conf missing/invalid ocsp cert source
// after
# nats.conf with leaf-first bundle
ocsp: { monitor_list: [443], ... } # with valid tls cert_file containing leaf first Defensive patterns
Strategy: validation
Validate before calling
certs, err := tls.X509KeyPair(certFile, keyFile) // ensure cert chain loads
if len(certs.Certificate) == 0 { return errors.New("empty certificate bundle") } Type guard
func hasLeaf(chain []*x509.Certificate) bool { return len(chain) > 0 } Prevention
- Always place the leaf certificate first in the bundle
- Test cert loading at deploy time, not only at OCSP monitor startup
- Avoid hand-edited bundle files
When it happens
Trigger: getOCSPIssuer is called with an empty cert chain (no cert_file bytes parsed) so certBundle has zero entries when getOCSPIssuerLocally runs.
Common situations: OCSP enabled in the server config but the certificate bundle failed to load, a misconfigured/misordered cert array, or an empty tls block passed to NewOCSPMonitor.
Related errors
- failed to parse ca_file: %v
- no issuers found
- invalid chain link
- no available OCSP servers
- 'cert_file' and 'cert_store' may not both be configured
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/6f4c018e5e5ba3a6.
Report an issue: GitHub.