grafana/k6 · error · errBrowserNotFoundInRegistry
browser not found in registry. make sure to set browser…
Error message
browser not found in registry. make sure to set browser type option in scenario definition in order to use the browser module
What it means
k6 pre-launches one browser per VU iteration on the IterStart event and stores it in an internal registry keyed by iteration ID; the browser module fetches it lazily via getBrowser (internal/js/modules/k6/browser/browser/registry.go:396). If nothing was launched — almost always because no browser type option was configured for the scenario — the lookup returns errBrowserNotFoundInRegistry. It is k6's guard against using k6/browser without the required options.
Solutions
- Set the browser type option in the scenario: `export const options = { scenarios: { ui: { executor: 'shared-iterations', options: { browser: { type: 'chromium' } } } } }`
- Or set it top-level so every scenario inherits it: `export const options = { browser: { type: 'chromium' } }`
- Import from 'k6/browser' (not 'k6/x/browser') and verify you run a modern k6 binary (browser module requires k6 >= 0.43; v1.x recommended)
- Check k6 output above this error — a failed browser launch for the iteration produces the same missing-registry lookup
Example fix
// before
import { browser } from 'k6/browser';
export default async function () {
const page = await browser.newPage(); // no browser type configured
}
// after
import { browser } from 'k6/browser';
export const options = {
scenarios: {
ui: { executor: 'shared-iterations', options: { browser: { type: 'chromium' } } },
},
};
export default async function () {
const page = await browser.newPage();
} Defensive patterns
Strategy: validation
Validate before calling
// k6 options are static — declare them unconditionally next to the browser import
import { browser } from 'k6/browser';
export const options = {
scenarios: {
ui: { executor: 'shared-iterations', vus: 1, options: { browser: { type: 'chromium' } } },
},
}; Prevention
- Always ship a browser type option (scenario-level or top-level) together with any k6/browser import
- Keep the options block and the browser import in the same review unit so they never drift apart
- Import from 'k6/browser', not 'k6/x/browser', and pin a modern k6 binary in CI
- Treat 'browser not found in registry' in review as a signal the options block was dropped
When it happens
Trigger: Importing k6/browser and calling chromium/browser() (or any page API) in a script whose options block lacks `browser: { type: 'chromium' }` — at scenario level or top level; browser options defined in one scenario while the browser code runs in another; a failed per-iteration browser launch leaving the registry empty.
Common situations: Browser examples copied from docs with the options block dropped; migration from the old k6/x/browser extension where the option was not required; options refactor that moved browser config out of the scenario; running a very old k6 binary that does not pre-launch browsers.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- unqouting K6_INSTANCE_SCENARIOS
- internal error while auto-attaching to browser pages
- internal error while getting browser target info
- invalid log level , should be one of: panic, fatal, error…
- missing required url
AI-assisted analysis of grafana/k6@01ffac6f24 (2026-08-18).
Data as JSON: /api/errors/5e779d13e0a73e28.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/browser/registry.go:33
"go.opentelemetry.io/otel/attribute"
oteltrace "go.opentelemetry.io/otel/trace"
"go.k6.io/k6/v2/internal/js/modules/k6/browser/chromium"
"go.k6.io/k6/v2/internal/js/modules/k6/browser/common"
"go.k6.io/k6/v2/internal/js/modules/k6/browser/env"
"go.k6.io/k6/v2/internal/js/modules/k6/browser/k6ext"
browsertrace "go.k6.io/k6/v2/internal/js/modules/k6/browser/trace"
"go.k6.io/k6/v2/internal/js/taskqueue"
k6event "go.k6.io/k6/v2/internal/event"
k6modules "go.k6.io/k6/v2/js/modules"
)
// errBrowserNotFoundInRegistry indicates that the browser instance
// for the iteration, which should have been initialized as a result
// of the IterStart event, has not been found in the registry. This
// might happen if browser type option is not set in scenario definition.
var errBrowserNotFoundInRegistry = errors.New("browser not found in registry. " +
"make sure to set browser type option in scenario definition in order to use the browser module")
// pidRegistry keeps track of the launched browser process IDs.
type pidRegistry struct {
mu sync.RWMutex
ids []int
}
// registerPid registers the launched browser process ID.
func (r *pidRegistry) registerPid(pid int) {
r.mu.Lock()
defer r.mu.Unlock()
r.ids = append(r.ids, pid)
}
// Pids returns the launched browser process IDs.
func (r *pidRegistry) Pids() []int {View on GitHub (pinned to 01ffac6f24)