hashicorp/nomad · error
unexpected file %q in snapshot
Error message
unexpected file %q in snapshot
What it means
The snapshot archive is expected to contain exactly three tar entries: meta.json, state.bin, and SHA256SUMS. This error is thrown when the tar reader encounters any other file name, meaning the archive does not match the internal snapshot format. It indicates the input is not a Nomad snapshot produced by this library (or was tampered with/repacked).
Source
Thrown at helper/snapshot/archive.go:226
if err != nil {
return fmt.Errorf("failed to read snapshot metadata: %v", err)
}
if err := json.Unmarshal(buf, &metadata); err != nil {
return fmt.Errorf("failed to decode snapshot metadata: %v", err)
}
case "state.bin":
if _, err := io.Copy(io.MultiWriter(snap, snapHash), archive); err != nil {
return fmt.Errorf("failed to read or write snapshot data: %v", err)
}
case "SHA256SUMS":
if _, err := io.Copy(&shaBuffer, archive); err != nil {
return fmt.Errorf("failed to read snapshot hashes: %v", err)
}
default:
return fmt.Errorf("unexpected file %q in snapshot", hdr.Name)
}
}
// Verify all the hashes.
if err := hl.DecodeAndVerify(&shaBuffer); err != nil {
return fmt.Errorf("failed checking integrity of snapshot: %v", err)
}
return nil
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Confirm the input file is a genuine Nomad snapshot (gzip'd tar with exactly meta.json, state.bin, SHA256SUMS) using tar -tzf; if not, obtain a real snapshot from the leader.
- Inspect the archive listing for spurious entries (directories, ._* files) and rebuild the archive removing them if a hand-edit is unavoidable.
- Check Nomad version compatibility: restore snapshots with the same or newer nomad operator snapshot restore tooling than the cluster that created them.
- Re-take the snapshot via nomad operator snapshot save rather than manually assembling archives.
Example fix
// before: piping an arbitrary tarball into Restore
snapshot.Restore(logger, backupTarball, r) // "unexpected file \"./\" in snapshot"
// after: validate the snapshot before restoring
if _, err := snapshot.Verify(snapshotFile); err != nil {
return fmt.Errorf("not a valid Nomad snapshot: %w", err)
}
snapshot.Restore(logger, snapshotFile, r) Defensive patterns
Strategy: validation
Validate before calling
// Ensure the input is a genuine Nomad snapshot before restoring
func isNomadSnapshot(in io.Reader) bool {
if _, err := snapshot.Verify(in); err != nil {
return false
}
if s, ok := in.(io.Seeker); ok {
s.Seek(0, 0)
}
return true
} Prevention
- Only feed archives produced by nomad operator snapshot save (or snapshot.New) into Restore/CopySnapshot.
- Never hand-edit or re-tar snapshot archives; treat them as opaque blobs.
- On macOS, avoid archives created by naive tar of directories that can add AppleDouble entries.
When it happens
Trigger: Calling snapshot.Verify/CopySnapshot/Restore on a tar archive that contains extra or differently-named members, e.g. a directory entry, OS metadata files like ._meta.json or PAX/global headers with odd names, or a user-made tarball that is not a real snapshot.
Common situations: Users hand-crafting or re-tarring snapshots; macOS-created archives containing AppleDouble files; restoring the wrong file (e.g. a config backup tarball) via nomad operator snapshot restore; archives round-tripped through tools that inject extra entries.
Related errors
- PluginID is required
- VolumeID is required
- ExternalID is required
- The '-template' flag is only valid when using 'go-template'
- A template must be supplied using '-template' when using go-
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/8b8e6004cd9bc28f.
Report an issue: GitHub.