projectdiscovery/nuclei · error
failed to create file: %w
Error message
failed to create file: %w
What it means
After downloading and rewriting an OpenAPI spec, the downloader writes it to <TempDir>/openapi/openapi-spec-<unixtime>.json; os.Create on that path failed and the underlying filesystem error (permission denied, no such file or directory, read-only file system, disk full) is wrapped with %w. TempDir comes from the InputOptions.TempDir the caller (input provider) supplied.
Source
Thrown at pkg/input/formats/openapi/downloader.go:118
modifiedJSON, err := json.Marshal(spec)
if err != nil {
return "", errors.Wrap(err, "failed to marshal modified spec")
}
// Create output directory
openapiDir := filepath.Join(tmpDir, "openapi")
if err := os.MkdirAll(openapiDir, 0755); err != nil {
return "", errors.Wrap(err, "failed to create openapi directory")
}
// Generate filename
filename := fmt.Sprintf("openapi-spec-%d.json", time.Now().Unix())
filePath := filepath.Join(openapiDir, filename)
// Write file
file, err := os.Create(filePath)
if err != nil {
return "", fmt.Errorf("failed to create file: %w", err)
}
defer func() {
_ = file.Close()
}()
if _, writeErr := file.Write(modifiedJSON); writeErr != nil {
_ = os.Remove(filePath)
return "", errors.Wrap(writeErr, "failed to write OpenAPI spec to file")
}
return filePath, nil
}
// SupportedExtensions returns the list of supported file extensions for OpenAPI
func (d *OpenAPIDownloader) SupportedExtensions() []string {
return []string{".json"}
}View on GitHub (pinned to 265b3a3dec)
Solutions
- Set a writable TempDir (InputOptions.TempDir) or ensure $TMPDIR points at a writable directory
- Verify with `touch <tmpdir>/openapi/test` that the effective user can create files there
- In containers, mount an emptyDir/tmpfs at /tmp or set TMPDIR to a writable volume
- Free disk space or raise the tmpfs size limit if the volume is full
Example fix
// SDK usage: pass a writable temp dir
// before
opts := provider.InputOptions{Options: options}
// after
opts := provider.InputOptions{
Options: options,
TempDir: os.TempDir(), // or a known-writable dir like "/var/tmp/nuclei"
} Defensive patterns
Strategy: validation
Validate before calling
dir := filepath.Join(tempDir, "openapi")
if err := os.MkdirAll(dir, 0o755); err != nil {
return fmt.Errorf("temp dir not writable: %w", err)
}
probe, err := os.Create(filepath.Join(dir, ".writecheck"))
if err != nil {
return fmt.Errorf("cannot create files in %s: %w", dir, err)
}
probe.Close()
os.Remove(probe.Name()) Try / catch
if err != nil && strings.Contains(err.Error(), "failed to create file") {
// point TempDir at a writable volume and retry once; otherwise fail with the FS error
} Prevention
- Set InputOptions.TempDir (or $TMPDIR) to a known-writable path in containers
- Mount an emptyDir/tmpfs at /tmp in hardened pods
- Monitor disk space in long-running scan workers
When it happens
Trigger: TempDir unset or pointing at a non-existent/read-only location; containers with a read-only rootfs and no writable /tmp; SELinux/AppArmor denying writes; disk exhausted; a file already existing where the openapi directory should be created; path too long.
Common situations: Running nuclei in hardened Docker/Kubernetes pods with read-only filesystems; minimal images lacking /tmp; CI runners with tiny tmpfs quotas; SDK callers passing an empty or relative TempDir.
Related errors
- could not create temp directory: %w
- could not create temp secrets file: %w
- ipv4 and/or ipv6 must be selected
- could not read profile file: %w
- could not write to temp secrets file: %w
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/b201c09250bffbe2.
Report an issue: GitHub.