grafana/k6 · error
creating temporary directory for downloads: %w
Error message
creating temporary directory for downloads: %w
What it means
When a browser context is created without an explicit downloadsPath, setDownloadsPath (browser_context.go:102) calls os.MkdirTemp(TMPDIR, 'artifacts-*') to create a scratch directory for downloaded files. If the OS refuses — unwritable or missing TMPDIR, ENOSPC, EACCES — context creation fails with 'creating temporary directory for downloads: %w' carrying the syscall error.
Source
Thrown at internal/js/modules/k6/browser/common/browser_context.go:102
// DownloadsPath is the path where downloads will be stored.
DownloadsPath string
}
// artifactsDirectory is the prefix for the temporary directory created for downloads.
const artifactsDirectory = "k6browser-artifacts-"
// setDownloadsPath sets the downloads path.
// If the provided path is empty, a temporary directory with
// an artifactsDirectory prefix will be created.
func (b *BrowserContext) setDownloadsPath(path string) error {
path = strings.TrimSpace(path)
if path != "" {
b.DownloadsPath = path
return nil
}
dir, err := os.MkdirTemp(os.TempDir(), artifactsDirectory+"*") //nolint:forbidigo
if err != nil {
return fmt.Errorf("creating temporary directory for downloads: %w", err)
}
b.DownloadsPath = dir
return nil
}
// cleanup cleans up the resources associated with the browser context.
func (b *BrowserContext) cleanup() error {
if err := os.RemoveAll(b.DownloadsPath); err != nil { //nolint:forbidigo
return fmt.Errorf("removing downloads path: %w", err)
}
b.DownloadsPath = ""
return nil
}
// NewBrowserContext creates a new browser context.
func NewBrowserContext(View on GitHub (pinned to 93accf6570)
Solutions
- Pass an explicit writable path: browser.newContext({ downloadsPath: '/writable/dir' }) on a volume you control
- Set TMPDIR to a writable directory for the k6 process
- Free disk space or raise emptyDir/ephemeral-storage limits if ENOSPC
- With readOnlyRootFilesystems, mount a writable tmpfs/emptyDir at /tmp
Example fix
// before
const ctx = browser.newContext() // auto temp dir in unwritable /tmp
// after
const ctx = browser.newContext({ downloadsPath: '/mnt/vol/downloads' }) Defensive patterns
Strategy: validation
Validate before calling
import { check } from 'k6'
// ensure a writable downloads dir before creating the context
const ctx = browser.newContext({ downloadsPath: '/writable/k6-downloads' }) Prevention
- Always pass an explicit downloadsPath on a writable volume
- Set TMPDIR to a writable directory in hardened containers
- With readOnlyRootFilesystem, mount a writable emptyDir at /tmp
When it happens
Trigger: TMPDIR unset, missing or unwritable; read-only root filesystem in a hardened container; disk full; CI runner with a tiny /tmp; security policy blocking writes under /tmp.
Common situations: Minimal distroless/scratch containers; Kubernetes pods with readOnlyRootFilesystem and no writable emptyDir for /tmp; disk quotas hit in CI.
Related errors
- setting downloads path: %w
- open() failed; reason: unable to access the file system
- removing downloads path: %w
- both K6_CLOUD_METRICS_PUSH_URL and K6_CLOUD_TEST_RUN_TOKEN m
- K6_CLOUD_LOGS_PUSH_URL requires K6_CLOUD_TEST_RUN_TOKEN
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/a61fe08ee8fc64d9.
Report an issue: GitHub.