grafana/k6 · error
newResolver(%+v): %w
Error message
newResolver(%+v): %w
What it means
Thrown while creating a browser NetworkManager (i.e., when a new browser context/page initializes networking) if the DNS resolver cannot be built from the test's dns options. The only real failure path is an invalid dns.ttl string, which surfaces as newResolver(...): parsing TTL: invalid DNS TTL: <value> in the wrapped chain.
Source
Thrown at internal/js/modules/k6/browser/common/network_manager.go:111
wg sync.WaitGroup
}
// NewNetworkManager creates a new network manager.
func NewNetworkManager(
ctx context.Context,
customMetrics *k6ext.CustomMetrics,
s session,
fm *FrameManager,
parent *NetworkManager,
ei eventInterceptor,
) (*NetworkManager, error) {
vu := k6ext.GetVU(ctx)
state := vu.State()
resolver, err := newResolver(state.Options.DNS)
if err != nil {
return nil, fmt.Errorf("newResolver(%+v): %w", state.Options.DNS, err)
}
m := NetworkManager{
BaseEventEmitter: NewBaseEventEmitter(ctx),
ctx: ctx,
// TODO: Pass an internal logger instead of basing it on k6's logger?
// See https://go.k6.io/k6/v2/js/modules/k6/browser/issues/54
logger: log.New(state.Logger, GetIterationID(ctx)),
session: s,
parent: parent,
frameManager: fm,
resolver: resolver,
vu: vu,
customMetrics: customMetrics,
reqIDToRequest: make(map[network.RequestID]*Request),
reqIDToRequestWillBeSentEvent: make(map[network.RequestID]*network.EventRequestWillBeSent),
reqIDToRequestPausedEvent: make(map[network.RequestID]*fetch.EventRequestPaused),
extraInfoTracker: newExtraInfoTracker(),View on GitHub (pinned to 93accf6570)
Solutions
- Set dns.ttl to a single valid value: '0', 'inf', or one duration like '1m'
- Remove or override the dns block for browser scenarios if HTTP-only options leak in via --config or exported options
- Validate the duration syntax: number plus unit s/m/h (no 'hr', no negatives, no lists)
- When both HTTP and browser tests share options, keep ttl single-valued so both stacks accept it
Example fix
// before (k6 options, valid for HTTP module but breaks browser module)
export const options = { dns: { ttl: '60s,5m', select: 'first' } };
// after
export const options = { dns: { ttl: '60s', select: 'first' } }; Defensive patterns
Strategy: validation
Validate before calling
// fail fast at init instead of at page creation
const TTL = __ENV.K6_DNS_TTL || '1m';
if (!/^(0|inf|\d+(\.\d+)?(ms|s|m|h))$/.test(TTL)) {
throw new Error(`invalid dns.ttl: ${TTL}`);
}
export const options = { dns: { ttl: TTL } }; Type guard
function isValidTtl(v) {
return v === '0' || v === 'inf' || v === '' || /^\d+(\.\d+)?(ms|s|m|h)$/.test(v);
} Prevention
- Keep dns.ttl single-valued; never reuse HTTP-style TTL lists in browser tests
- Lint exported options in CI for dns-ttl syntax
- Remember the full chain: this fires at first page creation, not at parse time
When it happens
Trigger: Creating a page/context while k6 options contain dns.ttl that parseTTL cannot parse: anything other than '0', 'inf', empty, or a single valid duration (e.g. 'abc', '-1m', or a comma list like '60s,5m' that k6's HTTP stack accepts but the browser module does not split).
Common situations: Reusing an existing k6 HTTP options block with a comma-separated TTL list in a browser test; typo'd duration units ('1hr' instead of '1h'); negative TTL values; environment-specific options files injected via --config.
Related errors
- parsing TTL: %w
- invalid DNS TTL: %s
- IP %s is in a blacklisted range %q
- scenario name can't be empty
- setupTimeout must be positive
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/0271bf0127283046.
Report an issue: GitHub.