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.BufferView on GitHub (pinned to 93accf6570)
Solutions
- Verify K6_CLOUD_HOST (or --cloud-host) and the k6 Cloud token belong to the same environment
- Upgrade k6 to the latest release so the presigned-URL request matches the current cloud API
- Confirm the cloud project supports browser artifact storage and the token has upload permissions
- 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
- Keep K6_CLOUD_HOST and the cloud token from the same environment
- Update k6 regularly so presigned-URL requests match the current cloud API
- Verify the project has browser-artifact storage entitlements before relying on cloud uploads
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
- unexpected HTTP error from %s: %d %s
- creating upload request: %w
- uploading archive: %w
- updating extra HTTP headers: %w
- Run `k6 cloud login` to authenticate, or check the docs for
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/a326423e69b0ab46.
Report an issue: GitHub.