crowdsecurity/crowdsec · error

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

Error message

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

What it means

doQueryRange treats any non-200 HTTP status from VictoriaLogs as a failure. After the retry budget is exhausted it returns "bad HTTP response code: %d: %s: %w" including the status code and response body. Note it wraps `err`, which is typically nil at this point, so the final %w adds no extra cause.

Source

Thrown at pkg/acquisition/modules/victorialogs/internal/vlclient/vl_client.go:141

		case <-ticker.C:
			resp, err := lc.Get(ctx, uri)
			if err != nil {
				if ok := lc.shouldRetry(); !ok {
					return fmt.Errorf("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
			}

			n, largestTime, err := lc.readResponse(ctx, resp, c)
			if err != nil {
				return fmt.Errorf("querying range: %w", err)
			}

			if !infinite && n < lc.config.Limit {
				lc.Logger.Infof("Got less than %d results (%d), stopping", lc.config.Limit, n)
				close(c)

				return nil
			}

View on GitHub (pinned to 909b515798)

Solutions

  1. Read the embedded response body in the error message — it usually states the exact server-side problem
  2. Verify the URL path points at VictoriaLogs' query range endpoint (e.g. /select/logsql/query_range)
  3. Add or fix authentication credentials if the instance is protected (401/403)
  4. Fix the LogsQL query parameters in the DSN if the server returns 400
  5. Increase max_failure_duration if 429 rate limiting is transient
Defensive patterns

Strategy: retry

Validate before calling

// verify endpoint and auth upfront
const res = await fetch(baseURL + "/select/logsql/query_range", { headers: authHeaders() })
if (res.status === 401 || res.status === 403) throw new Error("check credentials")

Try / catch

try {
  await runAcquisition()
} catch (e) {
  const m = /bad HTTP response code: (\d+)/.exec(String(e))
  if (m && m[1] === "429") await sleep(backoff)
  else if (m) log.error("VictoriaLogs returned", m[1], e.message)
  else throw e
}

Prevention

When it happens

Trigger: VictoriaLogs responds with 4xx/5xx to the query_range request and shouldRetry() returns false — e.g. 400 for a malformed query, 401/403 when authentication is required, 429 on rate limit, 500 on server error.

Common situations: Wrong query expression in the DSN (bad MetricsQL/LogsQL), missing auth credentials against a protected instance, overloaded VictoriaLogs returning 5xx, or a reverse proxy returning 404 for a wrong path.

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/d667a29f09fa0048. Report an issue: GitHub.