crowdsecurity/crowdsec · error

unexpected http code : %s

Error message

unexpected http code : %s

What it means

The CTI client's doRequest treats any HTTP status other than 200 OK and 404 Not Found as an error, returning fmt.Errorf("unexpected http code : %s", resp.Status). Called by GetIPInfo, SearchIPs and Fire, this surfaces any non-2xx (other than the specially-handled 404) response from the remote API as a generic unexpected-status error.

Source

Thrown at pkg/cticlient/client.go:74

		return nil, err
	}

	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		if resp.StatusCode == http.StatusForbidden {
			return nil, ErrUnauthorized
		}

		if resp.StatusCode == http.StatusTooManyRequests {
			return nil, ErrLimit
		}

		if resp.StatusCode == http.StatusNotFound {
			return nil, ErrNotFound
		}

		return nil, fmt.Errorf("unexpected http code : %s", resp.Status)
	}

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	return respBody, nil
}

func (c *CrowdsecCTIClient) GetIPInfo(ip string) (*SmokeItem, error) {
	ctx := context.TODO()

	body, err := c.doRequest(ctx, http.MethodGet, smokeEndpoint+"/"+ip, nil)
	if err != nil {
		if errors.Is(err, ErrNotFound) {
			return &SmokeItem{}, nil
		}

View on GitHub (pinned to 909b515798)

Solutions

  1. Check resp.Status in the error to see the actual code returned by the server.
  2. For 401/403: verify the API key configured for the CTI client is valid and active.
  3. For 429: back off and retry later; the API quota is exhausted.
  4. For 5xx: check the service's status page and retry; it is a server-side issue.
  5. Verify network/proxy settings if an intermediary is intercepting requests.
Defensive patterns

Strategy: try-catch

Validate before calling

// verify credentials before calling
if apiKey == "" {
    return fmt.Errorf("CTI API key not configured")
}

Try / catch

item, err := client.GetIPInfo(ctx, ip)
if err != nil {
    var nf *cticlient.ErrNotFound
    if errors.As(err, &nf) { /* unknown IP */ }
    // otherwise inspect resp.Status: 401/403 -> fix key, 429 -> back off, 5xx -> retry later
    log.Warnf("CTI request failed: %v", err)
}

Prevention

When it happens

Trigger: Calling GetIPInfo/SearchIPs/Fire when the remote endpoint answers with 401 (invalid API key), 403 (forbidden), 429 (rate limited), 5xx (server error), or any other status the client doesn't special-case.

Common situations: Expired or wrong CTT/CTI API key; exceeding the API quota (429); CAPI/CTI outage returning 502/503; proxy/firewall returning an HTML error page with a 403/502 status.

Related errors


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