grafana/k6 · error

unexpected HTTP error from %s: %d %s

Error message

unexpected HTTP error from %s: %d %s

What it means

CheckResponse returns this error when the cloud API replies with a non-2xx status whose body cannot be unmarshalled into the expected ResponseError JSON, and the status is not one that httperr.ClassifyStatus maps to a known error (it handles 401 Unauthorized and 403 Forbidden). It is the last-resort message: it preserves the request URL, the numeric status code, and the status text so the failure can still be diagnosed.

Source

Thrown at internal/cloudapi/v6/client.go:90

	if r == nil {
		return errUnknown
	}

	if c := r.StatusCode; c >= 200 && c <= 299 {
		return nil
	}

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

	var payload ResponseError
	if err := json.Unmarshal(data, &payload); err != nil {
		if classified := httperr.ClassifyStatus(r.StatusCode); classified != nil {
			return classified
		}
		return fmt.Errorf(
			"unexpected HTTP error from %s: %d %s",
			r.Request.URL,
			r.StatusCode,
			http.StatusText(r.StatusCode),
		)
	}
	payload.Response = r
	return payload
}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Read the URL and status in the message: 5xx usually means a transient gateway/Cloud issue, so retry after a short wait
  2. Verify K6_CLOUD_HOST and the stack URL point at the real API host (e.g. https://<stack>.grafana.net)
  3. If a proxy/WAF sits in the path, bypass it or allowlist the k6 API endpoints
  4. For persistent 4xx, compare the request URL against the API docs to find the misrouted endpoint

Example fix

# before
K6_CLOUD_HOST=http://internal-proxy:8080 k6 cloud script.js
# after
unset K6_CLOUD_HOST
k6 cloud script.js  # uses the stack URL from `k6 cloud login`
Defensive patterns

Strategy: retry

Try / catch

if err := client.UploadTest(ctx, name, projectID, arc); err != nil {
    var re cloudapiv6.ResponseError
    if errors.As(err, &re) {
        // structured API error: handle by re.Response.StatusCode
    } else if strings.Contains(err.Error(), "unexpected HTTP error") {
        // unclassified status with non-JSON body: retry 5xx with backoff, escalate 4xx
    }
}

Prevention

When it happens

Trigger: Any cloudapiv6 call (ValidateToken, UploadTest, StartTest, list commands) receives an unexpected status such as 502/503/504 or 418 with a non-JSON body (HTML error page, plain text, empty), so both json.Unmarshal and ClassifyStatus fail to produce a structured error.

Common situations: A corporate proxy, service mesh, or WAF intercepting requests to the Grafana Cloud host and returning an HTML block page; transient gateway 502/503 during a Grafana Cloud incident; K6_CLOUD_HOST pointing at a non-API endpoint that serves HTML.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/21bf1b2f5e8bafa1. Report an issue: GitHub.