grafana/k6 · warning
marshaling hosts option
Error message
marshaling hosts option: %w
What it means
When the k6 browser module launches Chromium, it converts the k6 `hosts` option (types.NullHosts) into --host-resolver-rules by round-tripping it through JSON into a map[string]string. This error means json.Marshal of the hosts option failed at that conversion step. Because NullHosts marshals as a plain map[string]string, this failure is a defensive guard that is essentially unreachable on released k6 builds; seeing it usually indicates an internal type change between k6 versions or a broken custom build.
Solutions
- Re-run the same script with the hosts option removed to confirm the failure is hosts-specific
- Verify hosts entries are simple "hostname": "ip" or "hostname": "ip:port" pairs in options.hosts / K6_HOSTS
- Upgrade k6 to a single consistent version so lib/types and the browser module match
- If it reproduces on stock k6, capture K6_BROWSER_LOG=debug output and report it upstream
Example fix
// before
export const options = { hosts: { 'test.k6.io': new Date() } }; // non-string value
// after
export const options = { hosts: { 'test.k6.io': '1.2.3.4' } }; // plain host->ip mapping Defensive patterns
Strategy: validation
Validate before calling
// In the k6 script, validate hosts entries before the run starts
export function setup() {
const hosts = __ENV.K6_HOSTS || '';
for (const pair of hosts.split(',')) {
if (!pair) continue;
const [host, ip] = pair.split('=');
if (!host || !ip || !/^\d+\.\d+\.\d+\.\d+(:\d+)?$/.test(ip.trim())) {
throw new Error(`Invalid hosts entry: ${pair} (expected host=ip[:port])`);
}
}
} Prevention
- Keep hosts option values as plain strings: host -> ip or ip:port
- Use one consistent k6 version for lib and browser module
- Smoke-test the script with hosts disabled when diagnosing launch failures
When it happens
Trigger: Launching the browser while the k6 `hosts` option is set (options.hosts or K6_HOSTS), and the internal NullHosts value failing to serialize. Only realistic if the NullHosts type/MarshalJSON changed between mismatched k6 versions, or in a forked/custom build.
Common situations: Upgrading k6 across versions where the hosts option internal representation changed; running a custom xk6 build against an incompatible lib; practically never on stock releases.
Understand the failure class
Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.
Related errors
- unmarshaling hosts option
- missing presigned url in response body
- parse isChecked options of selector
- parse isDisabled options of selector
- parse isEditable options of selector
AI-assisted analysis of grafana/k6@8d06114777 (2026-08-18).
Data as JSON: /api/errors/602c3912325a952c.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/chromium/browser_type.go:534
if currHostResolver, ok := flags["host-resolver-rules"]; ok {
hostResolver = append(hostResolver, fmt.Sprintf("%s", currHostResolver))
}
// Add the host resolver rules.
//
// This is done by marshaling the k6 hosts option to JSON and then
// unmarshaling it to a map[string]string. This is done because the
// k6 v0.42 changed Hosts from a map to types.NullHosts and doesn't
// expose the map anymore.
//
// TODO: A better way to do this would be to handle the resolver
// rules by communicating with Chromium (and then using Hosts's
// Match method) instead of passing the rules via the command line
// to Chromium.
var rules map[string]string
b, err := json.Marshal(k6opts.Hosts)
if err != nil {
return fmt.Errorf("marshaling hosts option: %w", err)
}
if err := json.Unmarshal(b, &rules); err != nil {
return fmt.Errorf("unmarshaling hosts option: %w", err)
}
for k, v := range rules {
hostResolver = append(hostResolver, fmt.Sprintf("MAP %s %s", k, v))
}
if len(hostResolver) > 0 {
sort.Strings(hostResolver)
flags["host-resolver-rules"] = strings.Join(hostResolver, ",")
}
return nil
}
// makeLogger makes and returns an extension wide logger.
func makeLogger(ctx context.Context, envLookup env.LookupFunc) (*log.Logger, error) {
var (View on GitHub (pinned to 8d06114777)