grafana/k6 · error
parsing TTL: %w
Error message
parsing TTL: %w
What it means
Intermediate wrap in newResolver: the k6types-based parseTTL helper rejected the dns.ttl string from options. It appears inside the chain 'newResolver(...): parsing TTL: invalid DNS TTL: <value>' whenever a new browser page/context is created, pointing squarely at the test's DNS configuration.
Source
Thrown at internal/js/modules/k6/browser/common/network_manager.go:169
"connectionaborted": network.ErrorReasonConnectionAborted,
"connectionclosed": network.ErrorReasonConnectionClosed,
"connectionfailed": network.ErrorReasonConnectionFailed,
"connectionrefused": network.ErrorReasonConnectionRefused,
"connectionreset": network.ErrorReasonConnectionReset,
"internetdisconnected": network.ErrorReasonInternetDisconnected,
"namenotresolved": network.ErrorReasonNameNotResolved,
"timedout": network.ErrorReasonTimedOut,
"failed": network.ErrorReasonFailed,
}
}
// Returns a new Resolver.
// Copied with minor changes from
// https://github.com/grafana/k6/blob/fb70bc6f3d3f22a40e65f32deea3cea1b6d70a76/js/runner.go#L459
func newResolver(conf k6types.DNSConfig) (k6netext.Resolver, error) {
ttl, err := parseTTL(conf.TTL.String)
if err != nil {
return nil, fmt.Errorf("parsing TTL: %w", err)
}
dnsSel := conf.Select
if !dnsSel.Valid {
dnsSel = k6types.DefaultDNSConfig().Select
}
dnsPol := conf.Policy
if !dnsPol.Valid {
dnsPol = k6types.DefaultDNSConfig().Policy
}
return k6netext.NewResolver(
net.LookupIP, ttl, dnsSel.DNSSelect, dnsPol.DNSPolicy), nil
}
// Parse a string representation of TTL to time.Duration.
// Copied from https://github.com/grafana/k6/blob/fb70bc6f3d3f22a40e65f32deea3cea1b6d70a76/js/runner.go#L479
func parseTTL(ttlS string) (time.Duration, error) {
ttl := time.Duration(0)View on GitHub (pinned to 93accf6570)
Solutions
- Fix options.dns.ttl to a single valid duration or '0'/'inf'
- Check overridden config sources: --config file, K6_DNS_TTL env var, cloud-originated options
- Rule out list syntax ('1m,5m') which is unsupported here
- Re-run with a minimal script to confirm the dns block is the culprit
Example fix
# before K6_DNS_TTL='1m,5m' k6 run script.js # after K6_DNS_TTL='1m' k6 run script.js
Defensive patterns
Strategy: validation
Validate before calling
const m = /newResolver\(.*parsing TTL: invalid DNS TTL: (.+)/.exec(err.message);
if (m) throw new Error(`fix options.dns.ttl: '${m[1]}' is not 0|inf|<duration>`); Type guard
function isValidTtl(v) {
return v === '0' || v === 'inf' || /^\d+(\.\d+)?(ms|s|m|h)$/.test(v);
} Prevention
- Audit --config files and K6_DNS_TTL in CI for list syntax
- Unit-check option generation when templating scripts
- Note empty ttl is valid (default applied); lists are not
When it happens
Trigger: Browser page creation with options.dns.ttl set to a string that is not '0', 'inf', empty, or parseable by ParseExtendedDuration (typos, unknown units, negative values, comma-separated lists).
Common situations: Copy-pasted options from k6 HTTP tests using TTL lists; CI injecting options via --config or environment (K6_DNS_TTL) with a bad value; unit mismatch after editing '600s' to '10m' style values by hand.
Related errors
- newResolver(%+v): %w
- invalid DNS TTL: %s
- hostname %s matches a blocked pattern %q
- IP %s is in a blacklisted range %q
- k6/experimental/browser has been graduated, please use k6/br
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/56ecfb38ea415d36.
Report an issue: GitHub.