crowdsecurity/crowdsec · error

unauthorized

Error message

unauthorized

What it means

ErrUnauthorized is the sentinel error returned when the CrowdSec CTI API answers HTTP 403 Forbidden, meaning the API key is rejected or lacks access to the endpoint. It is returned by doRequest and surfaced through CrowdsecCTI/Fire/GetIPInfo calls.

Source

Thrown at pkg/cticlient/client.go:23

	"encoding/json"
	"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 += "?"

View on GitHub (pinned to 909b515798)

Solutions

  1. Verify the CTI API key in your config/env is correct and active in the CrowdSec console
  2. Regenerate the API key at https://app.crowdsec.net and update your configuration
  3. Check errors.Is(err, cticlient.ErrUnauthorized) in your caller and disable/flag CTI enrichment on auth failure

Example fix

// before
resp, err := ctiClient.GetIPInfo(ip)
// after
resp, err := ctiClient.GetIPInfo(ip)
if errors.Is(err, cticlient.ErrUnauthorized) {
    log.Warning("CTI key rejected, disabling CTI enrichment")
}
Defensive patterns

Strategy: try-catch

Validate before calling

// guard: key must be set before any CTI call
if apiKey == "" { return errors.New("CTI API key not configured") }

Type guard

null

Try / catch

resp, err := ctiClient.GetIPInfo(ip)
if errors.Is(err, cticlient.ErrUnauthorized) {
    // disable CTI enrichment, do not retry
}

Prevention

When it happens

Trigger: Any CTI call (GetIPInfo, Fire) where the API responds with 403: invalid/expired/revoked API key, or key without entitlement for the endpoint.

Common situations: CTI_API_KEY set incorrectly (typo, whitespace, wrong env); key revoked in the CrowdSec console; free-tier key used against an endpoint it can't access.

Understand the failure class

Related errors


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