{"record":{"id":"ccb7becedfacba44","repo":"hashicorp/nomad","slug":"failed-to-create-temp-snapshot-file-v","errorCode":null,"errorMessage":"failed to create temp snapshot file: %v","messagePattern":"failed to create temp snapshot file: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"helper/snapshot/snapshot.go","lineNumber":269,"sourceCode":"// Restore takes the snapshot from the reader and attempts to apply it to the\n// given Raft instance.\nfunc Restore(logger hclog.Logger, in io.Reader, r *raft.Raft) error {\n\t// Wrap the reader in a gzip decompressor.\n\tdecomp, err := gzip.NewReader(&readWrapper{in, 0})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to decompress snapshot: %v\", err)\n\t}\n\tdefer func() {\n\t\tif err := decomp.Close(); err != nil {\n\t\t\tlogger.Error(\"Failed to close snapshot decompressor\", \"error\", err)\n\t\t}\n\t}()\n\n\t// Make a scratch file to receive the contents of the snapshot data so\n\t// we can avoid buffering in memory.\n\tsnap, err := os.CreateTemp(\"\", \"snapshot\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create temp snapshot file: %v\", err)\n\t}\n\tdefer func() {\n\t\tif err := snap.Close(); err != nil {\n\t\t\tlogger.Error(\"Failed to close temp snapshot\", \"error\", err)\n\t\t}\n\t\tif err := os.Remove(snap.Name()); err != nil {\n\t\t\tlogger.Error(\"Failed to clean up temp snapshot\", \"error\", err)\n\t\t}\n\t}()\n\n\t// Read the archive.\n\tvar metadata raft.SnapshotMeta\n\tif err := read(decomp, &metadata, snap); err != nil {\n\t\treturn fmt.Errorf(\"failed to read snapshot file: %v\", err)\n\t}\n\n\tif err := concludeGzipRead(decomp); err != nil {\n\t\treturn err","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/helper/snapshot/snapshot.go#L251-L287","documentation":"Restore() streams a snapshot archive into Raft without buffering it in memory, so it first creates a scratch temp file via os.CreateTemp. This error wraps any failure from that temp file creation, with the underlying os error appended. It indicates the process could not obtain a temporary file, usually an OS/environment problem rather than corrupted snapshot data.","triggerScenarios":"Calling Restore (via snapshotRestore) when os.CreateTemp(\"\", \"snapshot\") fails — e.g. the default temp directory (TMPDIR/tmp) does not exist, is not writable, the disk is full, or the process lacks permission to create files there.","commonSituations":"Containers launched with a read-only or unwritable /tmp; TMPDIR pointing at a nonexistent directory; disk-quota exhaustion on the node; running under a hardened security profile (noexec/no-temp files) or a stripped-down container image missing /tmp.","solutions":["Check the wrapped %v cause: verify the temp directory exists, is writable, and has free space (df, ls -ld $TMPDIR).","Set TMPDIR (or os.TempDir behavior) to a writable path before running the process.","Check filesystem quotas and mount flags (read-only, noexec) on the temp volume.","Run the process as a user with permission to create files in the temp directory."],"exampleFix":"// before (unwritable default temp dir)\nsnap, err := os.CreateTemp(\"\", \"snapshot\") // fails: open /tmp/snapshot...: read-only file system\n// after\n// launch with a writable temp dir, e.g. in the service unit/container:\n// Environment=TMPDIR=/var/lib/myapp/tmp   (and ensure the dir exists and is writable)","handlingStrategy":"validation","validationCode":"tmp := os.TempDir()\nif fi, err := os.Stat(tmp); err != nil || !fi.IsDir() {\n    return fmt.Errorf(\"temp dir %s unavailable: %w\", tmp, err)\n}\nprobe, err := os.CreateTemp(tmp, \"snapshot-probe\")\nif err != nil { return fmt.Errorf(\"cannot write temp files: %w\", err) }\nprobe.Close(); os.Remove(probe.Name())","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure /tmp (or $TMPDIR) exists, is writable, and has free disk space in every deployment (Dockerfile: RUN mkdir -p /tmp).","Avoid read-only root filesystems without a writable tmpfs mount.","Monitor disk usage and inodes on the node.","In tests or sandboxes, set TMPDIR explicitly to a known-writable directory."],"tags":["filesystem","temp-file","snapshot-restore","io"],"backgroundTag":"temp-file-creation-failed","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}