grafana/k6 · error

invalid url

Error message

invalid url %q

What it means

Intended to be returned when the url= value of K6_BROWSER_SCREENSHOTS_OUTPUT fails url.ParseRequestURI. The guard is 'err != nil && u.Scheme != "" && u.Host != ""', but Go's ParseRequestURI returns a nil *url.URL on failure, so in practice this branch almost never fires and malformed URLs are often accepted silently. When it does fire (or via the related nil hazard), the fix is the same: supply a valid absolute http/https URL.

Solutions

  1. Use a fully-qualified absolute URL: url=https://upload.example.com/
  2. Verify the URL independently (curl -I) before putting it in the env var, since the parser's validation is loose
  3. If you maintain this code, note the guard should be err != nil && (u == nil || ...) — as written the message is nearly unreachable

Example fix

# before
export K6_BROWSER_SCREENSHOTS_OUTPUT='url=cdn.example.com/upload'
# after
export K6_BROWSER_SCREENSHOTS_OUTPUT='url=https://cdn.example.com/upload'
Defensive patterns

Strategy: validation

Validate before calling

const v = process.env.K6_BROWSER_SCREENSHOTS_OUTPUT ?? '';
const urlPart = v.split(',').find(p => p.startsWith('url='));
if (urlPart) {
  let u;
  try { u = new URL(urlPart.slice(4)); } catch { u = null; }
  if (!u || (u.protocol !== 'http:' && u.protocol !== 'https:')) {
    throw new Error('url= must be an absolute http(s) URL with scheme and host');
  }
}

Prevention

When it happens

Trigger: Setting url= to a non-URL like 'url=localhost:9200/upload' or 'url=/upload' — values that fail request-URI parsing. Most such inputs are silently stored rather than rejected, surfacing later as upload failures.

Common situations: Omitting the scheme (example.com instead of https://example.com) in CI env vars; using a host:port value without a scheme; the error usually appears only in edge cases due to the guard logic, so verify URLs manually.

Related errors


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

Appendix: source

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

			hh := strings.Split(k, ".")
			if len(hh) != 2 {
				return presignedURLConfig{}, fmt.Errorf("format of header must be header.k=v, received %q", s)
			}

			k = hh[0]
			hk = hh[1]

			if hk == "" {
				return presignedURLConfig{}, fmt.Errorf("empty header key, received %q", s)
			}
		}

		switch k {
		case "url":
			u, err := url.ParseRequestURI(v)
			if err != nil && u.Scheme != "" && u.Host != "" {
				return presignedURLConfig{}, fmt.Errorf("invalid url %q", s)
			}
			presignedURL.getterURL = v
		case "basePath":
			presignedURL.basePath = v
		case "header":
			presignedURL.headers[hk] = hv
		default:
			return presignedURLConfig{}, fmt.Errorf("invalid option %q", k)
		}
	}

	if presignedURL.getterURL == "" {
		return presignedURLConfig{}, errors.New("missing required url")
	}

	return presignedURL, nil
}

View on GitHub (pinned to 01ffac6f24)