hashicorp/nomad · error
failed to finalize snapshot: %v
Error message
failed to finalize snapshot: %v
What it means
This error wraps the failure of tar.Writer.Close() while finalizing the snapshot tar archive in helper/snapshot/archive.go write(). Close() flushes any buffered data and writes the tar end-of-archive blocks; if the underlying output writer (out io.Writer) returns an error there (e.g. disk full on a file sink, closed pipe, broken connection to storage), it is surfaced as 'failed to finalize snapshot'. All prior writes may have succeeded, so the failure is purely at archive-finalization/flush time on the destination writer.
Source
Thrown at helper/snapshot/archive.go:163
var shaBuffer bytes.Buffer
if err := hl.Encode(&shaBuffer); err != nil {
return fmt.Errorf("failed to encode snapshot hashes: %v", err)
}
if err := archive.WriteHeader(&tar.Header{
Name: "SHA256SUMS",
Mode: 0600,
Size: int64(shaBuffer.Len()),
ModTime: now,
}); err != nil {
return fmt.Errorf("failed to write snapshot hashes header: %v", err)
}
if _, err := io.Copy(archive, &shaBuffer); err != nil {
return fmt.Errorf("failed to write snapshot metadata: %v", err)
}
// Finalize the archive.
if err := archive.Close(); err != nil {
return fmt.Errorf("failed to finalize snapshot: %v", err)
}
return nil
}
// read takes a reader and extracts the snapshot metadata and the snapshot
// itself, and also checks the integrity of the data. You must arrange to call
// Close() on the returned object or else you will leak a temporary file.
func read(in io.Reader, metadata *raft.SnapshotMeta, snap io.Writer) error {
// Start a new tar reader.
archive := tar.NewReader(in)
// Create a hash list that we will use to compare with the SHA256SUMS
// file in the archive.
hl := newHashList()
// Populate the hashes for all the files we expect to see. The check at
// the end will make sure these are all present in the SHA256SUMS fileView on GitHub (pinned to 482b49bf1a)
Solutions
- Check free disk space / write permissions on the snapshot destination and retry after freeing space
- If streaming to a remote sink, verify the sink connection and retry the snapshot operation
- Inspect the wrapped %v error for the true underlying cause and fix that writer
- If writing to an HTTP response, ensure the client keeps the connection open for the full snapshot download
Example fix
// before
f, _ := os.Create(path)
snapshot.Store(f)
// after
f, err := os.Create(path)
if err != nil { return err }
defer f.Close()
if err := snapshot.Store(f); err != nil {
return fmt.Errorf("snapshot write failed (check disk space/permissions on %s): %w", path, err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Go has no pre-call check, but validate the sink before writing:
info, err := os.Stat(targetDir)
if err != nil || !info.IsDir() {
return fmt.Errorf("snapshot target dir invalid: %v", err)
}
// ensure writable
probe, err := os.CreateTemp(targetDir, "snap-probe-*")
if err != nil {
return fmt.Errorf("snapshot target not writable: %v", err)
}
probe.Close()
os.Remove(probe.Name()) Type guard
// errors.As to inspect the underlying writer failure
func unwrapFinalizeErr(err error) error {
if err != nil && strings.Contains(err.Error(), "failed to finalize snapshot") {
var inner error
if _, scan := fmt.Sscanf(err.Error(), "failed to finalize snapshot: %v", &inner); scan == nil {
return inner
}
}
return err
} Try / catch
if err := snapshot.Store(out); err != nil {
if strings.Contains(err.Error(), "failed to finalize snapshot") {
log.Error("snapshot finalize failed (disk/network on destination)", "err", err)
// free space / reset sink, then retry
return retryStore()
}
return err
} Prevention
- Monitor free disk space on snapshot destinations and alert before it runs out
- Keep the HTTP client/connection open until the snapshot stream is fully received
- Validate sink connectivity to remote snapshot storage before taking snapshots
- Always check errors on the underlying writer, not just the snapshot call
When it happens
Trigger: Calling snapshot write()/Store.Store/TakeSnapshot where the destination io.Writer errors during Close: writing to a full disk, a closed or broken pipe (e.g. HTTP response writer closed client-side mid-snapshot), a network writer (S3/consul sink) timing out during flush, or an os.File whose write fails at the tail.
Common situations: Disk quota/full filesystem on the node storing the snapshot; client disconnects while downloading a snapshot via the Consul HTTP API; transient network failure to a remote snapshot sink; output file handle closed prematurely by surrounding code.
Related errors
- failed to read or write snapshot data: %v
- Failed to copy snapshot to temporary file: %v
- failed to write snapshot metadata header: %v
- failed to write snapshot metadata: %v
- failed to write snapshot data header: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/c0c47e8d0240b776.
Report an issue: GitHub.