hashicorp/nomad · error
Failed to load snapshot from archive: %w
Error message
Failed to load snapshot from archive: %w
What it means
RedactSnapshot wraps any failure from RestoreFromArchive, which parses the snapshot archive (tar.gz) and rebuilds the FSM and store. This means the input file could not be read as a valid Raft snapshot archive: bad format, corruption, unsupported structure, or unreadable content. The original error is preserved via %w for errors.As/Is inspection.
Source
Thrown at helper/raftutil/snapshot.go:59
err = fsm.RestoreWithFilter(r, filter)
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to restore from snapshot: %w", err)
}
select {
case err := <-errCh:
return nil, nil, nil, err
case meta := <-metaCh:
return fsm, fsm.State(), meta, nil
}
}
func RedactSnapshot(srcFile *os.File) error {
srcFile.Seek(0, 0)
fsm, store, meta, err := RestoreFromArchive(srcFile, nil)
if err != nil {
return fmt.Errorf("Failed to load snapshot from archive: %w", err)
}
iter, err := store.RootKeys(nil)
if err != nil {
return fmt.Errorf("Failed to query for root keys: %v", err)
}
for {
raw := iter.Next()
if raw == nil {
break
}
rootKey := raw.(*structs.RootKey)
if rootKey == nil {
break
}
if len(rootKey.WrappedKeys) > 0 {
rootKey.KeyID = rootKey.KeyID + " [REDACTED]"View on GitHub (pinned to 482b49bf1a)
Solutions
- Verify the file is a complete, valid snapshot archive (gzip/tar readable; e.g. `tar tzf snapshot.tar`) and re-download/re-take the snapshot if not.
- Check the wrapped error with errors.Unwrap to see the underlying cause (tar format, checksum, or FSM decode failure) and fix that specific issue.
- Confirm the snapshot came from the same or compatible product version as the tool doing the redaction.
- Ensure the file is seekable and readable: RestoreFromArchive seeks to 0 first; a closed or read-only fd will fail.
Example fix
// before
err := raftutil.RedactSnapshot(f) // f is a truncated/partial snapshot
// after
if fi, serr := f.Stat(); serr == nil && fi.Size() == 0 {
return fmt.Errorf("snapshot file is empty; re-run consul snapshot save")
}
err := raftutil.RedactSnapshot(f) Defensive patterns
Strategy: validation
Validate before calling
func validateSnapshotFile(f *os.File) error {
fi, err := f.Stat()
if err != nil {
return err
}
if fi.Size() == 0 {
return fmt.Errorf("snapshot file is empty")
}
// sniff gzip magic
br := bufio.NewReader(f)
magic, _ := br.Peek(2)
f.Seek(0, 0)
if len(magic) < 2 || magic[0] != 0x1f || magic[1] != 0x8b {
return fmt.Errorf("not a gzip snapshot archive")
}
return nil
} Try / catch
err := raftutil.RedactSnapshot(f)
var inner error
if err != nil && errors.Unwrap(err) != nil {
inner = errors.Unwrap(err)
log.Printf("snapshot load failed: %v (cause: %v)", err, inner)
} Prevention
- Always verify snapshot archives with the producer tool's verify command (e.g. `consul snapshot inspect`) before redacting.
- Check file size > 0 and gzip magic before passing to RedactSnapshot.
- Use consistent versions between snapshot producer and redaction tool.
- Avoid copying snapshots mid-transfer; compare checksums after download.
When it happens
Trigger: Calling helper/raftutil.RedactSnapshot with a *os.File whose contents are not a valid snapshot archive: empty file, truncated download, non-snapshot file, corrupt tar/gz stream, or an archive missing required snapshot members (meta.json, state.bin, logs.dat).
Common situations: Operator redacts a snapshot that was copied incompletely (scp/ctl-c mid-transfer), a snapshot produced by an incompatible Consul version, a file that is actually a BoltDB raft.db rather than a snapshot archive, or a 0-byte file created by the CLI before writing.
Related errors
- failed to open snapshot dir: %v
- Failed to query for root keys: %v
- Could not re-encode redacted key: %v
- Failed to create redacted snapshot: %v
- Failed to copy snapshot to temporary file: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/72dd0da880793e8f.
Report an issue: GitHub.