grafana/k6 · error

missing presigned url in response body

Error message

missing presigned url in response body

What it means

The browser module's RemoteFilePersister uploads artifacts (screenshots, traces) to k6 Cloud. It first POSTs to a presigned-URL endpoint and expects a body with a non-empty URLs array; if the response decodes but the list is empty (file_persister.go:185-198), no presigned upload URL was granted and the artifact upload cannot proceed.

Source

Thrown at internal/js/modules/k6/browser/storage/file_persister.go:195

	bb, err := json.Marshal(b)
	if err != nil {
		return nil, fmt.Errorf("marshaling request body: %w", err)
	}

	return bb, nil
}

func readPresignedURLResponse(resp *http.Response) (PresignedURLResponse, error) {
	var rb PresignedURLResponse

	decoder := json.NewDecoder(resp.Body)
	err := decoder.Decode(&rb)
	if err != nil {
		return PresignedURLResponse{}, fmt.Errorf("decoding response body: %w", err)
	}

	if len(rb.URLs) == 0 {
		return PresignedURLResponse{}, errors.New("missing presigned url in response body")
	}

	return rb, nil
}

// newFileUploadRequest creates a new HTTP request to upload a file as a multipart
// form to the presigned URL received from the server.
func newFileUploadRequest(
	ctx context.Context,
	resp PresignedURLResponse,
	data io.Reader,
) (*http.Request, error) {
	// we don't support multiple presigned URLs at the moment.
	psu := resp.URLs[0]

	// copy all form fields received from a presigned URL
	// response to the multipart form fields.
	var form bytes.Buffer

View on GitHub (pinned to 93accf6570)

Solutions

  1. Verify K6_CLOUD_HOST (or --cloud-host) and the k6 Cloud token belong to the same environment
  2. Upgrade k6 to the latest release so the presigned-URL request matches the current cloud API
  3. Confirm the cloud project supports browser artifact storage and the token has upload permissions
  4. If artifact upload is not needed for this run, disable it or run locally to unblock the test
Defensive patterns

Strategy: retry

Validate before calling

// Preflight the cloud endpoint with the same token before the run
// (outside k6): curl -H "Authorization: Token $K6_CLOUD_TOKEN" $K6_CLOUD_HOST/v1/check
// Expect 200; otherwise fix host/token pairing before running browser cloud tests.

Prevention

When it happens

Trigger: Running k6 cloud (or cloud-exported browser tests) where the artifact service answers 200 OK but returns zero URLs: environment mismatch between the auth token and K6_CLOUD_HOST, a k6 build whose upload contract differs from the cloud API, or a project without browser-artifact storage entitlements.

Common situations: Pointing k6 at a different cloud environment than the token belongs to; self-hosted or air-gapped installations without S3 upload support; version skew between an old k6 binary and new cloud API (or vice versa); expired or mis-scoped API tokens.

Related errors


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