grafana/k6 · error

internal error while getting browser target info: %w

Error message

internal error while getting browser target info: %w

What it means

Returned by Browser.initEvents when target.GetTargetInfo() fails. k6 deliberately makes this dummy call right after SetAutoAttach to work around a Chromium bug where setAutoAttach does not wait for new targets (see the linked Chromium review in the source). Its failure indicates the CDP session is broken at a point where even a trivial read-only call fails, so browser creation aborts with this 'internal error' message.

Source

Thrown at internal/js/modules/k6/browser/common/browser.go:262

				} else if event.typ == EventConnectionClose {
					b.logger.Debugf("Browser:initEvents:EventConnectionClose", "")
					return
				}
			}
		}
	}()

	action := target.SetAutoAttach(true, true).WithFlatten(true)
	if err := action.Do(cdp.WithExecutor(b.vuCtx, b.conn)); err != nil {
		return fmt.Errorf("internal error while auto-attaching to browser pages: %w", err)
	}

	// Target.setAutoAttach has a bug where it does not wait for new Targets being attached.
	// However making a dummy call afterwards fixes this.
	// This can be removed after https://chromium-review.googlesource.com/c/chromium/src/+/2885888 lands in stable.
	action2 := target.GetTargetInfo()
	if _, err := action2.Do(cdp.WithExecutor(b.vuCtx, b.conn)); err != nil {
		return fmt.Errorf("internal error while getting browser target info: %w", err)
	}

	return nil
}

// connectionOnAttachedToTarget is called when Connection receives an attachedToTarget
// event. Returning false will stop the event from being processed by the connection.
func (b *Browser) connectionOnAttachedToTarget(eva *target.EventAttachedToTarget) bool {
	// This allows to attach targets to the same browser context as the current
	// one, and to the default browser context.
	//
	// We don't want to hold the lock for the entire function
	// (connectionOnAttachedToTarget) run duration, because we want to avoid
	// possible lock contention issues with the browser context being closed while
	// we're waiting for it. So, we do the lock management in a function with its
	// own defer.
	isAllowedBrowserContext := func() bool {
		b.contextMu.RLock()

View on GitHub (pinned to 93accf6570)

Solutions

  1. Check Chrome/browser container memory limits and logs for OOM or hangs
  2. Increase K6_BROWSER_TIMEOUT for slow or loaded machines
  3. Confirm remote Chrome is not being restarted concurrently (orchestrator, browserless pool recycling)
  4. Retry launch once; if it consistently fails, capture K6_BROWSER_DEBUG=true output and report to k6

Example fix

# before
k6 run test.js  # browser hangs during setup, call times out

# after
K6_BROWSER_DEBUG=true K6_BROWSER_TIMEOUT=120s k6 run test.js
Defensive patterns

Strategy: retry

Try / catch

function connectWithRetry(url, retries = 2) {
  for (let i = 0; i <= retries; i++) {
    try {
      return chromium.connectOverCDP(url);
    } catch (e) {
      const m = String(e.message);
      if (i < retries && m.includes('getting browser target info')) { sleep(3); continue; }
      throw e;
    }
  }
}

Prevention

When it happens

Trigger: Same family as the auto-attach failure: connection closed/dropped during setup; remote Chrome process exiting mid-handshake; timeout cutting the round-trip; Chrome that became unresponsive (hung renderer/browser process).

Common situations: Chrome hanging under memory pressure right after start; container OOM killing the browser between the two CDP calls; flaky networking to remote browsers; extremely rare with healthy local Chrome.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/bc8f7c0a774c2bc5. Report an issue: GitHub.