crowdsecurity/crowdsec · error

no certificate in request

Error message

no certificate in request

What it means

ValidateCert extracts the client certificate from the gin request's TLS state. If the request carries no TLS session data or no peer certificates were presented, there is nothing to validate, so it fails with this error and the mTLS auth is refused.

Source

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

	return nil
}

func (ta *TLSAuth) checkAllowedOU(ous []string) error {
	for _, ou := range ous {
		if slices.Contains(ta.AllowedOUs, ou) {
			return nil
		}
	}

	return fmt.Errorf("client certificate OU %v doesn't match expected OU %v", ous, ta.AllowedOUs)
}

func (ta *TLSAuth) ValidateCert(c *gin.Context) (string, error) {
	// Checks cert validity, Returns true + CN if client cert matches requested OU
	var leaf *x509.Certificate

	if c.Request.TLS == nil || len(c.Request.TLS.PeerCertificates) == 0 {
		return "", errors.New("no certificate in request")
	}

	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")
	}

View on GitHub (pinned to 909b515798)

Solutions

  1. Configure the client to present its client certificate and key (e.g. curl --cert/--key or equivalent client config)
  2. Ensure the server requests/requires client certificates in its TLS listener settings
  3. Confirm the request goes directly to the TLS endpoint, not through a proxy that strips TLS client context

Example fix

// before
client: no certificate configured
// after (curl)
curl --cert client.pem --key client-key.pem --cacert ca.pem https://lapi:8080/...
Defensive patterns

Strategy: type-guard

Validate before calling

// caller-side guard before trusting mTLS identity
tlsState := c.Request.TLS
if tlsState == nil || len(tlsState.PeerCertificates) == 0 {
    c.AbortWithStatus(401)
}

Type guard

func hasClientCert(req *http.Request) bool {
    return req.TLS != nil && len(req.TLS.PeerCertificates) > 0
}

Try / catch

cn, err := ta.ValidateCert(c)
if err != nil {
    c.AbortWithStatus(http.StatusUnauthorized)
    return
}

Prevention

When it happens

Trigger: authTLS -> ValidateCert on a request where c.Request.TLS is nil or c.Request.TLS.PeerCertificates is empty, i.e. the client connected without presenting a client certificate.

Common situations: Client did not configure its client cert/key; server TLS listener configured with client auth mode that doesn't require certs (e.g. NoClientCert/VerifyClientCertIfGiven); a plain HTTP request hit the TLS-configured endpoint; misconfigured proxy terminating TLS.

Understand the failure class

Related errors


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