argoproj/argo-workflows · error
illegal file path: %s
Error message
illegal file path: %s
What it means
During unarchiving (tar extraction), the executor joins each tar header name with the destination and verifies the result stays inside dest (classic Zip Slip protection). If a tarball entry's path escapes the destination directory (e.g. '../evil' or absolute paths), extraction aborts with 'illegal file path'.
Source
Thrown at workflow/executor/executor.go:1143
gzr, err := file.GetGzipReader(f)
if err != nil {
return err
}
defer gzr.Close()
tr := tar.NewReader(gzr)
for {
header, err := tr.Next()
switch {
case errors.Is(err, io.EOF):
return nil
case err != nil:
return err
case header == nil:
continue
}
target := filepath.Join(dest, filepath.Clean(header.Name))
if !strings.HasPrefix(target, filepath.Clean(dest)+string(os.PathSeparator)) {
return fmt.Errorf("illegal file path: %s", header.Name)
}
switch header.Typeflag {
case tar.TypeSymlink:
// Validate symlink target before creating it
linkTarget := header.Linkname
if !filepath.IsAbs(linkTarget) {
linkTarget = filepath.Join(filepath.Dir(target), header.Linkname)
}
if !strings.HasPrefix(filepath.Clean(linkTarget), filepath.Clean(dest)+string(os.PathSeparator)) {
return fmt.Errorf("illegal symlink target: %s -> %s", header.Name, header.Linkname)
}
// Create parent directory if needed
if err := os.MkdirAll(filepath.Dir(target), 0o755); err != nil {
return err
}
err := os.Symlink(header.Linkname, target)
if err != nil {
return errView on GitHub (pinned to 35bff19146)
Solutions
- Repackage the artifact with relative, safe member paths (tar -C dir . instead of absolute paths)
- Do not load artifacts from untrusted sources, or inspect the tarball (tar -tf) before use
- Regenerate the upstream artifact if it was built with a faulty archiving step
- If you control the workflow, stage the artifact and extract manually with vetting instead of relying on auto-unarchive
Example fix
# before (upstream creates tarball with traversal) tar cf out.tar /work/../etc/passwd # after tar -C /work -cf out.tar .
Defensive patterns
Strategy: try-catch
Validate before calling
// Inspect a tarball for traversal entries before uploading it as an artifact: // tar -tf artifact.tar | grep -E '(^/|\.\./)' && echo "unsafe paths found"
Try / catch
if err := loadArtifacts(ctx); err != nil {
if strings.Contains(err.Error(), "illegal file path") {
// reject the artifact: it contains Zip-Slip paths; repackage upstream
}
} Prevention
- Build tarballs with relative paths (tar -C dir .)
- Never load archives from untrusted sources as input artifacts
- Scan third-party tarballs (tar -tf) for absolute/'..' entries before use
- Keep the executor updated so traversal protections are current
When it happens
Trigger: Extracting a (possibly malicious or malformed) tar artifact whose member names contain path traversal sequences ('..'), absolute paths, or symlink-crafted names that resolve outside the destination after filepath.Join+Clean.
Common situations: Untrusted third-party artifact (http artifact or someone else's output) containing a Zip-Slip payload; a build script that tarred absolute paths; corrupted/renamed entries where '..' slipped into the header name.
Related errors
- illegal symlink target: %s -> %s
- illegal file path after symlink resolution: %s resolves outs
- %s: Illegal file path
- artifact key %q must not contain '..'
- failed to tarball the output %s to %s: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/c5663dd9180662b8.
Report an issue: GitHub.