grafana/k6 · error

draining upload response body: %w

Error message

draining upload response body: %w

What it means

Raised in RemoteFilePersister.Persist when io.Copy(io.Discard, resp.Body) fails while draining the upload response body. Draining enables connection reuse; failure here means the response body could not be fully read — connection reset mid-body or a read timeout — even though the server may have accepted the upload. The drain error is treated as fatal for the persist call.

Source

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

func (r *RemoteFilePersister) Persist(ctx context.Context, path string, data io.Reader) (err error) {
	psResp, err := r.requestPresignedURL(ctx, path)
	if err != nil {
		return fmt.Errorf("requesting presigned url: %w", err)
	}

	req, err := newFileUploadRequest(ctx, psResp, data)
	if err != nil {
		return fmt.Errorf("creating upload request: %w", err)
	}

	resp, err := r.httpClient.Do(req) //nolint:gosec
	if err != nil {
		return fmt.Errorf("performing upload request: %w", err)
	}
	defer resp.Body.Close() //nolint:errcheck

	if _, err := io.Copy(io.Discard, resp.Body); err != nil {
		return fmt.Errorf("draining upload response body: %w", err)
	}

	if err := checkStatusCode(resp); err != nil {
		return fmt.Errorf("uploading: %w", err)
	}

	return nil
}

// requestPresignedURL will request a new presigned URL from the remote server
// and returns a [PresignedURLResponse] that contains the presigned URL details.
func (r *RemoteFilePersister) requestPresignedURL(ctx context.Context, path string) (PresignedURLResponse, error) {
	b, err := buildPresignedRequestBody(r.basePath, path)
	if err != nil {
		return PresignedURLResponse{}, fmt.Errorf("building request body: %w", err)
	}

	req, err := http.NewRequestWithContext(

View on GitHub (pinned to 01ffac6f24)

Solutions

  1. Retry the persist; the artifact may or may not have been uploaded
  2. Check for proxies/load balancers that truncate response bodies
  3. Verify network stability between k6 and the storage endpoint
  4. If persistent, disable cloud artifact upload and use local storage
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at internal/js/modules/k6/browser/storage/file_persister.go:113 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of grafana/k6@01ffac6f24 (2026-08-18). Data as JSON: /api/errors/77f656605c324a88. Report an issue: GitHub.