{"record":{"id":"d49b7316ac4aa652","repo":"argoproj/argo-workflows","slug":"failed-to-create-artifact-temporary-parent-directo","errorCode":null,"errorMessage":"failed to create artifact temporary parent directory %s: %w","messagePattern":"failed to create artifact temporary parent directory (.+?): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/executor/executor.go","lineNumber":328,"sourceCode":"\t\tartPath = path.Join(common.ExecutorArtifactBaseDir, art.Name)\n\t} else {\n\t\t// If we get here, it means the input artifact path overlaps with a user-specified\n\t\t// volumeMount in the container. Because we also implement input artifacts as volume\n\t\t// mounts, we need to load the artifact into the user specified volume mount,\n\t\t// as opposed to the `input-artifacts` volume that is an implementation detail\n\t\t// unbeknownst to the user.\n\t\tlogger.WithFields(logging.Fields{\"path\": art.Path, \"mountPath\": mnt.MountPath}).Info(ctx, \"Specified artifact path overlaps with volume mount, extracting to volume mount\")\n\t\tartPath = path.Join(common.ExecutorMainFilesystemDir, art.Path)\n\t}\n\n\t// The artifact is downloaded to a temporary location, after which we determine if\n\t// the file is a tarball or not. If it is, it is first extracted then renamed to\n\t// the desired location. If not, it is simply renamed to the location.\n\ttempArtPath := artPath + \".tmp\"\n\t// Ensure parent directory exist, create if missing\n\ttempArtDir := filepath.Dir(tempArtPath)\n\tif mkdirErr := os.MkdirAll(tempArtDir, 0o700); mkdirErr != nil {\n\t\treturn fmt.Errorf(\"failed to create artifact temporary parent directory %s: %w\", tempArtDir, mkdirErr)\n\t}\n\tctx, span := we.Tracing.StartLoadArtifact(ctx, artPath)\n\tdefer span.End()\n\terr = artDriver.Load(ctx, driverArt, tempArtPath)\n\tif err != nil {\n\t\tif art.Optional && argoerrs.IsCode(argoerrs.CodeNotFound, err) {\n\t\t\tlogger.WithField(\"name\", art.Name).Info(ctx, \"Skipping optional input artifact that was not found\")\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"artifact %s failed to load: %w\", art.Name, err)\n\t}\n\n\terr = we.unarchiveArtifact(ctx, art, tempArtPath, artPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tlogger.WithField(\"path\", artPath).Info(ctx, \"Successfully download file\")","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/executor/executor.go#L310-L346","documentation":"Before loading an artifact, the executor stages it at <artPath>.tmp and ensures the temporary file's parent directory exists via os.MkdirAll(tempArtDir, 0o700). If that OS call fails, this error wraps the underlying filesystem error.","triggerScenarios":"os.MkdirAll cannot create filepath.Dir(artPath + '.tmp') — e.g. the container filesystem is read-only, the mountpoint is not writable by the executor user, a component of the path is a file, or disk/quota issues prevent directory creation.","commonSituations":"Input artifact path inside a read-only volume or under /proc//etc; volume mounted root-owned with the pod running non-root; artifact path configured as a file (e.g. mounting a single-file ConfigMap) so a directory can't be created along that path.","solutions":["Check the wrapped mkdirErr in the message for the exact OS reason (EACCES, EROFS, ENOTDIR)","Make the artifact's parent directory a writable volume (emptyDir or writable PVC) and run the container as a user with write access","Ensure the artifact path's parent is not a mounted file (a single-file ConfigMap mount blocks directory creation)","Pick a writable mountPath (e.g. /mnt/data) for the input artifact"],"exampleFix":"# before\nartifacts:\n  - name: data\n    path: /etc/config/data.tar.gz   # read-only single-file mount\n# after\nartifacts:\n  - name: data\n    path: /mnt/work/data.tar.gz     # writable emptyDir mounted at /mnt/work","handlingStrategy":"validation","validationCode":"// Ensure the artifact path parent is writable before running the pod:\n// kubectl exec <pod> -- ls -ld /mnt/work   # check ownership and writability\n// Prefer dedicated writable volumes for artifact paths","typeGuard":null,"tryCatchPattern":"if err := loadArtifacts(ctx); err != nil {\n\tvar perr *fs.PathError\n\tif errors.As(err, &perr) && perr.Op == \"mkdir\" {\n\t\t// fix volume permissions/mount type, then retry\n\t}\n}","preventionTips":["Mount artifact paths on writable volumes (emptyDir/PVC), never read-only or single-file mounts","Run containers as a user with write access to the mount","Avoid paths under /etc, /proc, /sys or other read-only locations","Check the wrapped OS error (EACCES/EROFS/ENOTDIR) in the message"],"tags":["filesystem","artifacts","executor","permissions"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}