crowdsecurity/crowdsec · error

bad HTTP response code: %d: %s: %w

Error message

bad HTTP response code: %d: %s: %w

What it means

queryRange received a non-200 HTTP response from Loki and, after retries were exhausted, wraps the status code and response body. Note the wrapping uses err, which at this point is typically nil — the useful detail is the status code and body captured in the message.

Source

Thrown at pkg/acquisition/modules/loki/internal/lokiclient/loki_client.go:150

			return ctx.Err()
		case <-lc.t.Dying():
			return lc.t.Err()
		case <-ticker.C:
			resp, err := lc.Get(ctx, uri)
			if err != nil {
				if ok := lc.shouldRetry(); !ok {
					return fmt.Errorf("error querying range: %w", err)
				}
				lc.increaseTicker(ticker)
				continue
			}

			if resp.StatusCode != http.StatusOK {
				lc.Logger.Warnf("bad HTTP response code for query range: %d", resp.StatusCode)
				body, _ := io.ReadAll(resp.Body)
				resp.Body.Close()
				if ok := lc.shouldRetry(); !ok {
					return fmt.Errorf("bad HTTP response code: %d: %s: %w", resp.StatusCode, string(body), err)
				}
				lc.increaseTicker(ticker)
				continue
			}

			var lq LokiQueryRangeResponse
			if err := json.NewDecoder(resp.Body).Decode(&lq); err != nil {
				resp.Body.Close()
				if ok := lc.shouldRetry(); !ok {
					return fmt.Errorf("error decoding Loki response: %w", err)
				}
				lc.increaseTicker(ticker)
				continue
			}
			resp.Body.Close()
			lc.Logger.Tracef("Got response: %+v", lq)
			c <- &lq
			lc.resetFailStart()

View on GitHub (pinned to 909b515798)

Solutions

  1. Read the status code and body in the error to identify the Loki-side cause
  2. Validate the LogQL query string (e.g. loki-cli or the Loki UI)
  3. If 429: lower query frequency/limit or raise Loki rate limits
  4. If 5xx: check Loki server logs and cluster health
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: check the query returns 200
// curl -sG -o /dev/null -w '%{http_code}' loki:3100/loki/api/v1/query_range --data-urlencode 'query={job="app"}'

Try / catch

var httpErr *HTTPStatusError
if errors.As(err, &httpErr) && httpErr.Code == 429 {
    // back off / slow down query rate
} else if errors.As(err, &httpErr) {
    log.Errorf("loki rejected request: %d %s", httpErr.Code, httpErr.Body)
}

Prevention

When it happens

Trigger: Loki returns 4xx/5xx, e.g. 400 for an invalid query (bad LogQL selector), 429 rate limit, 503 when the distributor/ingester is unavailable.

Common situations: LogQL syntax errors in the datasource config; Loki rate limits hit (429); query beyond Loki's retention window returning 4xx.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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