hashicorp/nomad · error

error reading snapshot: %w

Error message

error reading snapshot: %w

What it means

streamAllocDir reads a tar-formatted snapshot of the previous allocation's directory over a pipe/tar reader. If the tar read returns a non-EOF error, Nomad aborts the extraction and wraps it as "error reading snapshot".

Source

Thrown at client/allocwatcher/alloc_watcher.go:684

					return fmt.Errorf("error chowning file %w", err)
				}
			}

			// We write in chunks so that we can test if the client
			// is still alive
			for !canceled() {
				n, err := tr.Read(buf)
				if n > 0 && (err == nil || err == io.EOF) {
					if _, err := f.Write(buf[:n]); err != nil {
						f.Close()
						return fmt.Errorf("error writing to file %q: %w", f.Name(), err)
					}
				}

				if err != nil {
					f.Close()
					if err != io.EOF {
						return fmt.Errorf("error reading snapshot: %w", err)
					}
					break
				}
			}

		}
	}

	if canceled() {
		return ctx.Err()
	}

	return nil
}

// NoopPrevAlloc does not block or migrate on a previous allocation and never
// returns an error.
type NoopPrevAlloc struct{}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Retry the allocation migration; the framework will reschedule if migration fails.
  2. Check the source alloc dir for corruption or missing files on the old client.
  3. Look at the wrapped inner error (e.g. unexpected EOF, pipe broken) and check client logs around the migration window.
  4. Upgrade Nomad if this recurs during node drain/migration — several tar/stream handling bugs were fixed over time.

Example fix

// no code fix; diagnose wrapped cause:
// error reading snapshot: archive/tar: unexpected EOF
// => old client's alloc dir changed mid-stream; retry migration on a stable node
Defensive patterns

Strategy: retry

Validate before calling

// precheck: verify the previous alloc's dir is readable and non-empty before migrating
if st, err := os.Stat(prevAllocDir); err != nil || !st.IsDir() {
    return fmt.Errorf("prev alloc dir unreadable: %w", err)
}

Try / catch

// wrap migration and retry on snapshot errors
err := migrateAllocDir(prevAlloc)
if err != nil && strings.Contains(err.Error(), "error reading snapshot") {
    // transient stream interruption; let the scheduler reschedule the alloc
    logger.Warn("snapshot read failed, waiting for reschedule", "err", err)
}

Prevention

When it happens

Trigger: The tar stream produced by the previous allocation's alloc dir reader (tar.Reader.Next / tr.Read) returns a non-io.EOF error — the stream was truncated, the underlying pipe/reader was closed prematurely, or the archive is corrupt.

Common situations: Previous allocation's client shut down while its alloc dir was still streaming; corrupted state on disk; network/pipe interruption between the migrating alloc reader and this goroutine.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/59d0278811f72305. Report an issue: GitHub.