projectdiscovery/katana · error

could not create new page

Error message

could not create new page

What it means

This error is wrapped by createBrowserPageFunc in katana's headless browser launcher when browser.Page(proto.TargetCreateTarget{}) fails. It means a new CDP target (tab/page) could not be created in the already-launched Chrome instance via the chromedp/rod DevTools protocol. The underlying error from rod (e.g. context deadline, browser crashed, connection lost) is preserved by errors.Wrap.

Source

Thrown at pkg/engine/headless/browser/browser.go:424

			tempDir, err = os.MkdirTemp("", "katana-chrome-data-*")
			if err != nil {
				return nil, errors.Wrap(err, "could not create temporary chrome data directory")
			}
			shouldCleanupTempDir = true
		}
	}

	browser, err := l.launchBrowserWithDataDir(tempDir)
	if err != nil {
		if shouldCleanupTempDir {
			_ = os.RemoveAll(tempDir)
		}
		return nil, err
	}

	page, err := browser.Page(proto.TargetCreateTarget{})
	if err != nil {
		return nil, errors.Wrap(err, "could not create new page")
	}

	successfulPageCreation := false
	defer func() {
		if !successfulPageCreation {
			_ = page.Close()
			if l.opts.ChromeWSUrl == "" {
				_ = browser.Close()
			}
			if shouldCleanupTempDir {
				_ = os.RemoveAll(tempDir)
			}
		}
	}()

	page = page.Sleeper(func() rodutils.Sleeper {
		return backoffCountSleeper(100*time.Millisecond, 1*time.Second, 3, func(d time.Duration) time.Duration {
			return d * 1

View on GitHub (pinned to e3e742739c)

Solutions

  1. Check that the Chrome process is still alive and re-launch the browser (recreate the Launcher) when this error occurs, instead of reusing a stale browser instance.
  2. Reduce concurrency (parallelism/page pool size) so Chrome is not overwhelmed and does not run out of memory or file descriptors.
  3. Update the browser binaries / katana version so the CDP protocol matches the installed Chrome version.
  4. Inspect the wrapped underlying error: if it is 'context deadline exceeded' the browser is hung — increase timeouts or restart it; if 'target closed' the browser crashed — check Chrome crash logs and resource limits (ulimit, cgroup memory).

Example fix

// before: reusing a possibly-dead browser from a cached launcher
page, err := cachedLauncher.GetPageFromPool()
if err != nil { return err } // "could not create new page" repeats forever

// after: detect dead browser and relaunch
page, err := cachedLauncher.GetPageFromPool()
if err != nil {
    _ = cachedLauncher.Close()
    cachedLauncher, err = launcher.NewLauncher(opts...)
    if err != nil { return err }
    page, err = cachedLauncher.GetPageFromPool()
}
Defensive patterns

Strategy: retry

Validate before calling

// verify the browser is alive before requesting a page
func browserAlive(l *launcher.Launcher) bool {
    // e.g. attempt a cheap CDP call or track process state
    return l != nil && l.BrowserHealthy()
}

Try / catch

page, err := l.GetPageFromPool()
if err != nil {
    if strings.Contains(err.Error(), "could not create new page") {
        // relaunch browser and retry once
        _ = l.Close()
        l, err = launcher.NewLauncher(opts...)
        if err == nil { page, err = l.GetPageFromPool() }
    }
    if err != nil { return err }
}

Prevention

When it happens

Trigger: Calling Launcher.GetPageFromPool() (or any code path using createBrowserPageFunc) when the Chrome process has crashed or exited, when the DevTools WebSocket connection has been dropped, when the browser was closed concurrently by another goroutine, or when CDP Target.createTarget times out against an overloaded/hung browser.

Common situations: Long-running crawls where Chrome was OOM-killed or crashed mid-run; running too many concurrent pages exhausting browser resources; Chrome version/protocol mismatch with the bundled rod protocol definitions; reusing a Launcher whose browser was already closed; sandboxed/containerized environments where Chrome dies shortly after launch.

Related errors


AI-assisted analysis of projectdiscovery/katana@e3e742739c (2026-09-03). Data as JSON: /api/errors/0371e1ba94ced76b. Report an issue: GitHub.