argoproj/argo-workflows · error
unable to remove attempted file download %s: %w
Error message
unable to remove attempted file download %s: %w
What it means
Load determined the blob key is actually a directory prefix. It previously created a local placeholder file at `path` while attempting a file download, and now must os.Remove it before re-creating the location as a directory. This error means the local filesystem refused the remove (permission, path is a non-empty dir, mount issues).
Source
Thrown at workflow/artifacts/azure/azure.go:159
} else if !bloberror.HasCode(origErr, bloberror.BlobNotFound) {
return fmt.Errorf("unable to download blob %s: %w", artifact.Azure.Blob, origErr)
}
isDir, err := azblobDriver.IsDirectory(ctx, artifact)
if err != nil {
return fmt.Errorf("unable to determine if %s is a directory: %w", artifact.Azure.Blob, err)
}
// It's not a directory and the file doesn't exist, Return the original NoSuchKey error.
if !isDir && !isEmptyFile {
return argoerrors.New(argoerrors.CodeNotFound, origErr.Error())
}
// When we tried to download the blob as a file, we created an empty file for the
// blob as a target. We need to delete that empty file so we can re-create as a directory.
err = os.Remove(path)
if err != nil {
return fmt.Errorf("unable to remove attempted file download %s: %w", path, err)
}
// It's a directory, so download all of the files.
err = azblobDriver.DownloadDirectory(ctx, containerClient, artifact, path)
if err != nil {
return fmt.Errorf("unable to download directory %s: %w", artifact.Azure.Blob, err)
}
return nil
}
// DownloadFile downloads a single file from Azure Blob Storage
func DownloadFile(ctx context.Context, containerClient *container.Client, blobName, path string) error {
blobClient := containerClient.NewBlobClient(blobName)
err := os.MkdirAll(filepath.Dir(path), 0755)
if err != nil {
return fmt.Errorf("unable to create dir for file %s: %w", path, err)View on GitHub (pinned to 35bff19146)
Solutions
- Point the artifact path at a fresh, dedicated directory (e.g. /mnt/out) that does not already contain content.
- Ensure the volume backing the path is writable by the executor user (not read-only).
- If the path exists as a non-empty dir from a previous step, use a unique path per step or clean it before.
- Run the pod/executor with sufficient permissions (securityContext) to delete the placeholder file.
- Check the wrapped os error: EACCES => permissions, EBUSY/EXDEV => mount layout, ENOTEMPTY => existing content.
Example fix
// before: artifact path collides with existing dir path: /mnt/src // after: dedicated writable output dir path: /mnt/out/artifacts
Defensive patterns
Strategy: validation
Validate before calling
st, err := os.Lstat(path)
if err == nil && st.IsDir() {
// destination occupied by a directory; clean or pick another path
if err := os.RemoveAll(path); err != nil { return err }
}
if err := unix.Access(filepath.Dir(path), unix.W_OK); err != nil { return err } Type guard
func writableArtifactPath(p string) error {
if fi, err := os.Lstat(p); err == nil && fi.IsDir() {
return fmt.Errorf("path %s is an existing directory", p)
}
return nil
} Prevention
- Use a fresh dedicated artifact directory (e.g. /mnt/out) per step
- Never point artifacts at read-only or shared mount roots
- Set matching fsGroup/runAsUser in securityContext for the executor
- Clean step output paths before downloads in the entrypoint script
When it happens
Trigger: os.Remove(path) fails because path is a non-empty directory (ADLS Gen2 downloaded a real directory with contents), the volume is read-only, the file is owned by another user, or path points at a protected mount point (e.g. artifact destination = a mounted volume root).
Common situations: Output/input artifact path set to an existing non-empty directory in the container, emptyDir mounted read-only, running argoexec as non-root while a prior step created the file as root.
Related errors
- failed to create parent directory for artifact %q at %s: %w
- failed to clear existing path for artifact %q at %s: %w
- unable to retrieve stats for downloaded file %s: %w
- os create %s: %w
- failed to create artifact temporary parent directory %s: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/9b353896674fb42f.
Report an issue: GitHub.