{"record":{"id":"4951da11ac4ec7b2","repo":"hashicorp/nomad","slug":"failed-to-rewind-snapshot-v","errorCode":null,"errorMessage":"failed to rewind snapshot: %v","messagePattern":"failed to rewind snapshot: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"helper/snapshot/snapshot.go","lineNumber":138,"sourceCode":"\tcompressor := gzip.NewWriter(out)\n\n\t// Write the archive.\n\tif err := write(compressor, metadata, snap); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to write snapshot file: %v\", err)\n\t}\n\n\t// Finish the compressed stream.\n\tif err := compressor.Close(); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to compress snapshot file: %v\", err)\n\t}\n\n\t// Sync the compressed file and rewind it so it's ready to be streamed\n\t// out by the caller.\n\tif err := archive.Sync(); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to sync snapshot: %v\", err)\n\t}\n\tif _, err := archive.Seek(0, 0); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to rewind snapshot: %v\", err)\n\t}\n\n\tchecksum := \"sha-256=\" + base64.StdEncoding.EncodeToString(hash.Sum(nil))\n\n\tkeep = true\n\treturn &Snapshot{archive, metadata.Index, checksum}, nil\n}\n\n// Index returns the index of the snapshot. This is safe to call on a nil\n// snapshot, it will just return 0.\nfunc (s *Snapshot) Index() uint64 {\n\tif s == nil {\n\t\treturn 0\n\t}\n\treturn s.index\n}\n\nfunc (s *Snapshot) Checksum() string {","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/helper/snapshot/snapshot.go#L120-L156","documentation":"After syncing, writeSnapshot rewinds the temp archive with archive.Seek(0, 0) so the caller can stream it out (e.g. HTTP response). A Seek failure on the local temp file is unexpected and indicates the archive file descriptor is broken, so snapshot creation fails with this error.","triggerScenarios":"New or NewFromFSM where archive.Seek(0, 0) returns an error: the temp file was closed or replaced unexpectedly, the file descriptor is invalid (EBADF), or an exotic filesystem doesn't support seeking on the temp file.","commonSituations":"TMPDIR on a filesystem without seek support (pipes/special filesystems); custom TMPDIR misconfiguration; corrupted file descriptor after earlier I/O failures.","solutions":["Ensure TMPDIR points to a regular local filesystem that supports seeking (not a pipe or procfs-like mount).","Check the wrapped %v cause for the errno (e.g. EBADF/ESPIPE) and fix the underlying file/environment issue.","Confirm no external cleanup (tmpwatch/tmpreaper) or code path closed the temp file mid-write.","Retry snapshot creation after fixing the environment."],"exampleFix":"// before: TMPDIR=/dev/shm-like or pipe-backed fs → ESPIPE\n// after\nexport TMPDIR=/var/lib/myapp/tmp   # regular seekable filesystem","handlingStrategy":"validation","validationCode":"// temp dir must be a regular, seekable filesystem\nif fi, err := os.Stat(os.TempDir()); err != nil || !fi.IsDir() {\n\treturn fmt.Errorf(\"invalid TMPDIR\")\n}","typeGuard":null,"tryCatchPattern":"snap, err := snapshot.New(...)\nif err != nil && strings.Contains(err.Error(), \"failed to rewind snapshot\") {\n\tlogger.Error(\"cannot seek snapshot temp file; check TMPDIR/filesystem\", \"err\", err)\n\treturn err\n}","preventionTips":["Point TMPDIR at a regular local filesystem, never pipes or pseudo-filesystems.","Don't disable or race with tmp-cleanup daemons (tmpwatch) during snapshot creation.","Verify the errno in the wrapped cause (ESPIPE/EBADF) to guide the fix.","Keep earlier snapshot steps healthy — a broken fd from a prior failure can cascade."],"tags":["filesystem","io","seek","snapshot"],"backgroundTag":"file-seek-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"}