argoproj/argo-workflows · error
failed to create destination %s: %w
Error message
failed to create destination %s: %w
What it means
saveArtifact failed to create the artifact destination file (<dstPath> under /var/run/argo/outputs/artifacts) via os.Create after its parent directory was made. The step's output artifact cannot be written. The wrapped OS error carries the concrete cause.
Source
Thrown at cmd/argoexec/commands/emissary.go:713
logger.WithField("srcPath", srcPath).Info(ctx, "no need to save artifact - on overlapping volume")
return nil
}
if _, err := os.Stat(srcPath); os.IsNotExist(err) { // might be optional, so we ignore
logger.WithField("srcPath", srcPath).WithError(err).Warn(ctx, "cannot save artifact")
return nil
}
dstPath := filepath.Join(varRunArgo, "/outputs/artifacts/", strings.TrimSuffix(srcPath, "/")+".tgz")
logger.WithFields(logging.Fields{
"src": srcPath,
"dst": dstPath,
}).Info(ctx, "saving artifact")
z := filepath.Dir(dstPath)
if err := os.MkdirAll(z, 0o755); err != nil { // chmod rwxr-xr-x
return fmt.Errorf("failed to create directory %s: %w", z, err)
}
dst, err := os.Create(dstPath)
if err != nil {
return fmt.Errorf("failed to create destination %s: %w", dstPath, err)
}
defer func() { _ = dst.Close() }()
if err = archive.TarGzToWriter(ctx, srcPath, gzip.DefaultCompression, dst); err != nil {
return fmt.Errorf("failed to tarball the output %s to %s: %w", srcPath, dstPath, err)
}
if err = dst.Close(); err != nil {
return fmt.Errorf("failed to close %s: %w", dstPath, err)
}
return nil
}
func saveParameter(ctx context.Context, template *wfv1.Template, srcPath string) error {
logger := logging.RequireLoggerFromContext(ctx)
if common.FindOverlappingVolume(template, srcPath) != nil {
logger.WithField("src", srcPath).Info(ctx, "no need to save parameter - on overlapping volume")
return nil
}View on GitHub (pinned to 35bff19146)
Solutions
- Check the wrapped error: EISDIR means the template's artifact path must point to a file, not a directory.
- Increase pod ulimits (RLIMIT_NOFILE) if EMFILE appears; reduce concurrent output saving.
- Free disk space if ENOSPC.
- Fix write permissions/UID for /var/run/argo/outputs (volume + securityContext).
Example fix
// before
outputs:
artifacts:
- name: dir-out
path: /tmp/results # directory -> os.Create fails EISDIR
// after: archive a file path (directories get tarballed from srcPath)
outputs:
artifacts:
- name: dir-out
path: /tmp/results.tgz Defensive patterns
Strategy: validation
Validate before calling
// ensure the artifact destination is a file path, not a directory path
if fi, err := os.Stat(dstPath); err == nil && fi.IsDir() {
return fmt.Errorf("artifact destination %s is a directory", dstPath)
}
// check fd headroom
var lim syscall.Rlimit
_ = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lim) Try / catch
err := runStep(ctx)
if err != nil && strings.Contains(err.Error(), "failed to create destination") {
if errors.Is(errors.Unwrap(err), syscall.EISDIR) {
return fixTemplateArtifactPath(ctx) // path must end in a file
}
return err
} Prevention
- Point artifact outputs at file paths, not directory paths
- Avoid saving dozens of artifacts from one step (fd exhaustion)
- Confirm the image securityContext allows writing under /var/run/argo/outputs
- Free disk space before workflows producing many large artifacts
When it happens
Trigger: os.Create(dstPath) fails: destination path is a directory, too many open files (EMFILE), disk full, or write permission denied on the newly created output directory.
Common situations: Artifact path in the template points at a directory instead of a file; hitting the pod's file-descriptor limit while many artifacts/parameters save concurrently; ENOSPC; SELinux/AppArmor denying writes.
Related errors
- failed to create directory %s: %w
- failed to close %s: %w
- failed to stat input artifact %q at %s: %w
- failed to create parent directory for artifact %q at %s: %w
- failed to stat artifact path %q at %s: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/02b99eea38d40475.
Report an issue: GitHub.