hashicorp/nomad · error
error evaluating symlink: %w
Error message
error evaluating symlink: %w
What it means
After creating a symlink from the archive, Nomad validates both the entry name and its link target with escapingfs.PathEscapesAllocDir to prevent path traversal. This error is returned when that security check itself fails (internal error evaluating paths), not when the symlink actually escapes.
Source
Thrown at client/allocwatcher/alloc_watcher.go:635
os.MkdirAll(name, os.FileMode(hdr.Mode))
// Can't change owner if not root or on Windows.
if euid == 0 {
if err := os.Chown(name, hdr.Uid, hdr.Gid); err != nil {
return fmt.Errorf("error chowning directory %w", err)
}
}
continue
}
// If the header is for a symlink we create the symlink
if hdr.Typeflag == tar.TypeSymlink {
if err = os.Symlink(hdr.Linkname, filepath.Join(dest, hdr.Name)); err != nil {
return fmt.Errorf("error creating symlink: %w", err)
}
for _, path := range []string{hdr.Name, hdr.Linkname} {
if escapes, err := escapingfs.PathEscapesAllocDir(dest, "", path); err != nil {
return fmt.Errorf("error evaluating symlink: %w", err)
} else if escapes {
return fmt.Errorf("archive contains symlink that escapes alloc dir")
}
}
continue
}
// If the header is a file, we write to a file
if hdr.Typeflag == tar.TypeReg {
fPath := filepath.Join(dest, hdr.Name)
if _, err := os.Lstat(fPath); err == nil {
if err := os.Remove(fPath); err != nil {
return fmt.Errorf("error removing existing file: %w", err)
}
}
f, err := os.Create(fPath)
if err != nil {
return fmt.Errorf("error creating file: %w", err)View on GitHub (pinned to 482b49bf1a)
Solutions
- Inspect the archive for malformed/invalid path entries (invalid characters, absolute paths)
- Re-snapshot or re-migrate the alloc dir to regenerate a clean archive
- Check escapingfs.PathEscapesAllocDir implementation and host filesystem errors in logs
- Reject the migration and redeploy the job instead of retrying with a corrupt archive
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate archive paths are well-formed before extraction: // reject headers whose Name/Linkname contain NUL bytes, absolute paths, or invalid separators
Type guard
func malformedArchivePath(p string) bool {
return p == "" || strings.ContainsRune(p, 0) || filepath.IsAbs(p)
} Try / catch
if err := watcher.Wait(ctx); err != nil {
if strings.Contains(err.Error(), "error evaluating symlink") {
log.Error("archive evaluation failed; treat as corrupt", "err", err)
}
return err
} Prevention
- Only migrate alloc dirs snapshotted by a trusted Nomad client
- Re-snapshot on evaluation failures instead of retrying the same archive
- Keep clients on the same Nomad version so escapingfs behavior matches
When it happens
Trigger: escapingfs.PathEscapesAllocDir(dest, "", path) returns a non-nil error for either hdr.Name or hdr.Linkname during tar extraction of a TypeSymlink entry.
Common situations: Malformed paths in a hand-crafted or corrupted archive (e.g. NUL bytes, invalid separators) that break path evaluation; filesystem errors during evaluation.
Related errors
- archive contains symlink that escapes alloc dir
- artifact includes symlink that resolves outside of sandbox
- running container as ContainerAdmin is unsafe; change the co
- ACL token not found
- running as user %q is disallowed
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/c91a2997a04356ee.
Report an issue: GitHub.