nats-io/nats-server · error

no issuers found

Error message

no issuers found

What it means

If the CA file and bundle produce no usable issuer (getOCSPIssuerLocally returns nil issuer without error — e.g. no trusted CA matched the leaf and no explicit issuer was in the bundle), getOCSPIssuer fails with "no issuers found".

Solutions

  1. Add the leaf's direct issuer (intermediate) as the second certificate in the cert bundle
  2. Ensure ca_file contains the CA that actually signed the leaf
  3. Omit ca_file to use the system default trust store if the chain is publicly trusted

Example fix

// before
# bundle: leaf only, ca_file = root that did not sign leaf
// after
cat leaf.pem intermediate.pem > bundle.pem
# or set ca_file to the intermediate that signed the leaf
Defensive patterns

Strategy: validation

Validate before calling

leaf := bundle[0]
// ensure the direct issuer is available before enabling OCSP
if len(bundle) < 2 && trustedCAs == nil { return errors.New("provide the leaf's issuer in bundle or ca_file") }

Prevention

When it happens

Trigger: getOCSPIssuerLocally returns (nil, nil): the leaf's issuer is not found among trustedCAs (when a CA pool was supplied) and certBundle has no second certificate.

Common situations: ca_file lists a root CA but the leaf is signed by an intermediate not present in the bundle; operator relies on the system trust store but the real issuer is missing; bundle contains only the leaf.

Related errors


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

Appendix: source

Thrown at server/ocsp.go:964

	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:
		return "good"
	case ocsp.Revoked:
		return "revoked"
	default:
		return "unknown"
	}
}

View on GitHub (pinned to 3a66a489d2)