hashicorp/nomad · error
archive contains object that escapes alloc dir
Error message
archive contains object that escapes alloc dir
What it means
If PathEscapesAllocDir determines that a tar entry (hdr.Name) would land outside the destination allocation directory, streamAllocDir refuses it with the literal error 'archive contains object that escapes alloc dir'. This is a security guard against path traversal (e.g. ../../) or absolute-path/symlink attacks carried inside the snapshot received from another node.
Source
Thrown at client/allocwatcher/alloc_watcher.go:599
buf := make([]byte, 1024)
for !canceled() {
// Get the next header
hdr, err := tr.Next()
// Snapshot has ended
if err == io.EOF {
return nil
}
if err != nil {
return fmt.Errorf("error streaming previous alloc %q for new alloc %q: %w",
p.prevAllocID, p.allocID, err)
}
if escapes, err := escapingfs.PathEscapesAllocDir(dest, "", hdr.Name); err != nil {
return fmt.Errorf("error evaluating object: %w", err)
} else if escapes {
return fmt.Errorf("archive contains object that escapes alloc dir")
}
if hdr.Name == errorFilename {
// Error snapshotting on the remote side, try to read
// the message out of the file and return it.
errBuf := make([]byte, int(hdr.Size))
if _, err := tr.Read(errBuf); err != nil && err != io.EOF {
return fmt.Errorf("error streaming previous alloc %q for new alloc %q; failed reading error message: %w",
p.prevAllocID, p.allocID, err)
}
return fmt.Errorf("error streaming previous alloc %q for new alloc %q: %s",
p.prevAllocID, p.allocID, string(errBuf))
}
// If the header is for a directory we create the directory
if hdr.Typeflag == tar.TypeDir {
name := filepath.Join(dest, hdr.Name)
os.MkdirAll(name, os.FileMode(hdr.Mode))View on GitHub (pinned to 482b49bf1a)
Solutions
- Inspect the previous alloc dir for symlinks or paths escaping the allocation directory and fix/remove them before rescheduling
- Verify the source node's integrity — this error can indicate a malicious snapshot; investigate the node
- Ensure tasks do not create symlinks outside their alloc dir (chroot/ isolation settings, task guidance)
- Upgrade Nomad if running a version with known escapingfs gaps, then retry the migration
Example fix
// before (inside task) ln -s /etc/passwd $NOMAD_ALLOC_DIR/leak // after ln -s $NOMAD_ALLOC_DIR/data/link-target $NOMAD_ALLOC_DIR/link # keep symlinks inside the alloc dir
Defensive patterns
Strategy: type-guard
Validate before calling
func entryEscapes(dest, name string) bool {
escapes, _ := escapingfs.PathEscapesAllocDir(dest, "", name)
return escapes
} Type guard
func isSafeEntry(dest string, hdr *tar.Header) bool {
escapes, err := escapingfs.PathEscapesAllocDir(dest, "", hdr.Name)
return err == nil && !escapes
} Try / catch
if err := migrate(); err != nil {
if strings.Contains(err.Error(), "escapes alloc dir") {
// security event: alert, quarantine snapshot, audit source node
}
return err
} Prevention
- Audit task scripts/templates for symlinks or writes targeting paths outside the alloc dir
- Never bypass the PathEscapesAllocDir check when handling migration snapshots
- Investigate any node producing such archives — it may be compromised
- Keep Nomad updated for the latest escapingfs/path-hardening fixes
When it happens
Trigger: The snapshot tar from the previous allocation contains an entry whose resolved path escapes dest: names with '..' components, absolute paths, or symlinks (including hardlink/linkname entries) that resolve outside the alloc dir.
Common situations: A compromised or malicious node sending a crafted snapshot during migration; tasks that created symlinks pointing outside their alloc dir; a buggy task writing paths with ../; fuzzed/corrupted archive producing path escapes.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- path escapes the alloc directory
- Reading secret file prohibited: %s
- error streaming previous alloc %q for new alloc %q: %w
- error evaluating object: %w
- archive contains symlink that escapes alloc dir
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/4e955f30d9896264.
Report an issue: GitHub.