projectdiscovery/katana · error
could not create temporary chrome data directory
Error message
could not create temporary chrome data directory
What it means
Thrown when os.MkdirTemp fails to create a temporary Chrome profile directory inside ChromeUser.HomeDir. Katana needs a writable per-run data dir to launch headless Chrome; without it the page cannot start. The wrap preserves the underlying OS error (e.g. permission denied, no such directory).
Source
Thrown at pkg/engine/headless/browser/browser.go:386
return err
}
func (l *Launcher) createBrowserPageFunc() (*BrowserPage, error) {
// When using ChromeWSUrl, we don't need temp directories
// since we're connecting to an existing browser
var tempDir string
shouldCleanupTempDir := false
if l.opts.ChromeWSUrl == "" {
if l.opts.UserDataDir != "" {
// Use user-provided data directory (preserve sessions/cookies)
tempDir = l.opts.UserDataDir
shouldCleanupTempDir = false
} else if l.opts.ChromeUser != nil {
var err error
tempDir, err = os.MkdirTemp(l.opts.ChromeUser.HomeDir, "chrome-data-*")
if err != nil {
return nil, errors.Wrap(err, "could not create temporary chrome data directory")
}
uid, err := strconv.Atoi(l.opts.ChromeUser.Uid)
if err != nil {
_ = os.RemoveAll(tempDir)
return nil, errors.Wrap(err, "invalid user ID")
}
gid, err := strconv.Atoi(l.opts.ChromeUser.Gid)
if err != nil {
_ = os.RemoveAll(tempDir)
return nil, errors.Wrap(err, "invalid group ID")
}
if err := os.Chown(tempDir, uid, gid); err != nil {
_ = os.RemoveAll(tempDir)
return nil, errors.Wrap(err, "could not change ownership of chrome data directory")
}
shouldCleanupTempDir = true
} else {View on GitHub (pinned to e3e742739c)
Solutions
- Verify ChromeUser.HomeDir exists and is writable by the process user (ls -ld; touch a test file).
- If running in Docker, ensure the home directory is created (useradd -m) or mount a writable volume there.
- Run the process as the ChromeUser or grant write permission on HomeDir (chown/chmod, securityContext).
- Check disk space (df -h) and that the filesystem is not mounted read-only.
- If a dedicated chrome user is unnecessary, leave ChromeUser nil so katana uses the default system temp dir.
Example fix
// before
u, _ := user.Lookup("chrome")
opts.ChromeUser = u // home may not exist
// after
if _, err := os.Stat(u.HomeDir); err != nil {
os.MkdirAll(u.HomeDir, 0o700)
os.Chown(u.HomeDir, mustAtoi(u.Uid), mustAtoi(u.Gid))
}
opts.ChromeUser = u Defensive patterns
Strategy: validation
Validate before calling
if opts.ChromeUser != nil {
if _, err := os.Stat(opts.ChromeUser.HomeDir); err != nil {
os.MkdirAll(opts.ChromeUser.HomeDir, 0o700) // or fall back to ChromeUser=nil
}
} Type guard
func usableDir(p string) bool {
fi, err := os.Stat(p)
return err == nil && fi.IsDir()
} Try / catch
page, err := l.createBrowserPageFunc(...)
if err != nil && strings.Contains(err.Error(), "temporary chrome data directory") {
l.opts.ChromeUser = nil // fall back to default temp dir
page, err = l.createBrowserPageFunc(...)
} Prevention
- Create and chown the chrome user's home directory in your image/entrypoint before launching.
- Run the process under the same user whose home you pass as ChromeUser.
- Monitor disk space on the volume hosting the home dir.
- Only set ChromeUser when a dedicated chrome user is actually required.
When it happens
Trigger: LauncherOptions.ChromeUser is set (non-nil) and os.MkdirTemp(l.opts.ChromeUser.HomeDir, "chrome-data-*") returns an error — HomeDir does not exist, is not writable by the current process, or the filesystem is full/read-only.
Common situations: Running katana as a different user than the owner of ChromeUser.HomeDir; container images where the chrome user's home was never created; read-only root filesystem; disk quota exhausted; account missing on the host so user.Lookup-derived HomeDir is invalid.
Related errors
- could not change ownership of chrome data directory
- could not create graph file
- captcha inject: %w
- unknown action type: %v
- invalid user ID
AI-assisted analysis of projectdiscovery/katana@e3e742739c (2026-09-03).
Data as JSON: /api/errors/623884747499b762.
Report an issue: GitHub.