crowdsecurity/crowdsec · warning

request quota exceeded, please reduce your request rate

Error message

request quota exceeded, please reduce your request rate

What it means

ErrLimit is the sentinel error returned when the CTI API responds HTTP 429 Too Many Requests, meaning the request quota for your API key has been exceeded. Returned by doRequest and surfaced through CrowdsecCTI calls.

Source

Thrown at pkg/cticlient/client.go:24

	"errors"
	"fmt"
	"io"
	"net/http"
	"strings"

	"github.com/crowdsecurity/crowdsec/pkg/apiclient/useragent"
	log "github.com/sirupsen/logrus"
)

const (
	CTIBaseUrl    = "https://cti.api.crowdsec.net/v2"
	smokeEndpoint = "/smoke"
	fireEndpoint  = "/fire"
)

var (
	ErrUnauthorized  = errors.New("unauthorized")
	ErrLimit         = errors.New("request quota exceeded, please reduce your request rate")
	ErrNotFound      = errors.New("ip not found")
	ErrDisabled      = errors.New("cti is disabled")
	ErrUnknown       = errors.New("unknown error")
	defaultUserAgent = useragent.Default()
)

type CrowdsecCTIClient struct {
	httpClient *http.Client
	apiKey     string
	Logger     *log.Entry
	UserAgent  string
}

func (c *CrowdsecCTIClient) doRequest(ctx context.Context, method string, endpoint string, params map[string]string) ([]byte, error) {
	url := CTIBaseUrl + endpoint
	if len(params) > 0 {
		url += "?"
		for k, v := range params {

View on GitHub (pinned to 909b515798)

Solutions

  1. Reduce CTI request rate or enable the local CTI cache to deduplicate lookups
  2. Upgrade your CTI subscription for a higher quota
  3. Back off and retry after a delay; treat ErrLimit as transient and fall back to empty SmokeItem

Example fix

// before
item, err := ctiClient.GetIPInfo(ip)
// after
item, err := ctiClient.GetIPInfo(ip)
if errors.Is(err, cticlient.ErrLimit) {
    time.Sleep(backoff)
    item, err = ctiClient.GetIPInfo(ip)
}
Defensive patterns

Strategy: retry

Validate before calling

null

Type guard

null

Try / catch

item, err := ctiClient.GetIPInfo(ip)
if errors.Is(err, cticlient.ErrLimit) {
    select { case <-time.After(backoff): case <-ctx.Done(): }
    item, err = ctiClient.GetIPInfo(ip)
}

Prevention

When it happens

Trigger: Any CTI call (GetIPInfo, Fire) when the per-key rate/quota limit is hit — HTTP 429 response from https://cti.api.crowdsec.net/v2.

Common situations: High-traffic CrowdSec instances enriching every alert with CTI lookups; missing/undersized local CTI cache causing repeated API hits; batch jobs iterating many IPs.

Related errors


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