crowdsecurity/crowdsec · error

(cache) %w

Error message

(cache) %w

What it means

During client-certificate validation, the result of the OCSP/CRL revocation check is memoized in a revocation cache. This error surfaces a previously cached failed revocation verdict: on an earlier request the revocation check returned an error (or determined the cert is revoked), that verdict was stored, and now ValidateCert replays it prefixed with '(cache)'. The current request is rejected without re-running OCSP/CRL.

Source

Thrown at pkg/apiserver/middlewares/v1/tls_auth.go:127

	if len(c.Request.TLS.VerifiedChains) == 0 {
		return "", errors.New("no verified cert in request")
	}

	// although there can be multiple chains, the leaf certificate is the same
	// we take the first one
	leaf = c.Request.TLS.VerifiedChains[0][0]

	if err := ta.checkAllowedOU(leaf.Subject.OrganizationalUnit); err != nil {
		return "", err
	}

	if ta.isExpired(leaf) {
		return "", errors.New("client certificate is expired")
	}

	if validErr, cached := ta.revocationCache.Get(leaf); cached {
		if validErr != nil {
			return "", fmt.Errorf("(cache) %w", validErr)
		}

		return leaf.Subject.CommonName, nil
	}

	okToCache := true

	var (
		validErr   error
		couldCheck bool
	)

	for _, chain := range c.Request.TLS.VerifiedChains {
		validErr, couldCheck = ta.checkRevocationPath(c.Request.Context(), chain)
		okToCache = okToCache && couldCheck

		if validErr != nil {
			break

View on GitHub (pinned to 909b515798)

Solutions

  1. Treat it as authoritative: the certificate was determined revoked — replace it with a freshly issued client certificate.
  2. Verify revocation status manually (openssl ocsp / fetch the CRL) to confirm the verdict.
  3. Restart the crowdsec LAPI server to clear the in-memory revocation cache if the verdict was based on a transient check error and the cert is confirmed valid.
  4. Reduce the revocation cache TTL in configuration if stale verdicts cause operational pain.
Defensive patterns

Strategy: retry

Validate before calling

// verify revocation out-of-band before connecting:
// openssl ocsp -issuer ca.pem -cert client.pem -url <ocsp_url>  (or fetch and inspect the CRL)

Try / catch

if _, err := validateCert(req); err != nil {
    if strings.Contains(err.Error(), "(cache)") {
        // verdict came from cache: re-issue the cert or wait for cache expiry; do not hot-loop retries
    }
}

Prevention

When it happens

Trigger: Every TLS client-auth request for a certificate whose cached revocation verdict (validErr) is non-nil — i.e. the check previously concluded 'certificate revoked by OCSP' or 'certificate revoked by CRL', or a check error deemed cacheable (okToCache was true because both OCSP and CRL were actually checked).

Common situations: A certificate that was genuinely revoked (admin revoked an agent/bouncer cert) still being presented by an old deployment; long cache TTL making a revoked cert keep failing after reissuance of the same cert; operators confused why the connection still fails after fixing the CA/CRL server, since the negative verdict persists until cache expiry.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/2db97e060b8194f2. Report an issue: GitHub.