{"record":{"id":"1d058c6e55afe9a6","repo":"argoproj/argo-workflows","slug":"unable-to-retrieve-stats-for-downloaded-file-s","errorCode":null,"errorMessage":"unable to retrieve stats for downloaded file %s: %w","messagePattern":"unable to retrieve stats for downloaded file (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/artifacts/azure/azure.go","lineNumber":131,"sourceCode":"\t\tWithField(\"blob\", artifact.Azure.Blob).\n\t\tInfo(ctx, \"Downloading from Azure Blob Storage\")\n\tcontainerClient, err := azblobDriver.newAzureContainerClient(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to create Azure Blob Container client: %w\", err)\n\t}\n\n\t// Assume we're not downloading a directory and try to download as a file, since this is\n\t// the most common case and we don't want the penalty of listing the blobs before we\n\t// download (to determine if it's a directory instead of a single file). If we get a\n\t// BlobNotFound error, then check if it's a directory and process accordingly. If the account\n\t// has HNS enabled (ADLS Gen 2), then there's an edge case with using the blob API to\n\t// access. The directory will be returned as an empty file, so check for that as well.\n\tvar isEmptyFile bool\n\torigErr := DownloadFile(ctx, containerClient, artifact.Azure.Blob, path)\n\tif origErr == nil {\n\t\tfileInfo, lstatErr := os.Lstat(path)\n\t\tif lstatErr != nil {\n\t\t\treturn fmt.Errorf(\"unable to retrieve stats for downloaded file %s: %w\", path, lstatErr)\n\t\t}\n\n\t\t// Empty file means it could be an ADLS Gen 2 account and we downloaded the\n\t\t// directory as an empty file -- we'll check below. If it's a non-empty file,\n\t\t// then we successfully downloaded a file blob.\n\t\tif fileInfo.Size() > 0 {\n\t\t\treturn nil\n\t\t}\n\t\tisEmptyFile = true\n\t} else if !bloberror.HasCode(origErr, bloberror.BlobNotFound) {\n\t\treturn fmt.Errorf(\"unable to download blob %s: %w\", artifact.Azure.Blob, origErr)\n\t}\n\n\tisDir, err := azblobDriver.IsDirectory(ctx, artifact)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to determine if %s is a directory: %w\", artifact.Azure.Blob, err)\n\t}\n","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/artifacts/azure/azure.go#L113-L149","documentation":"After DownloadFile succeeds in Load, the driver calls os.Lstat(path) to determine the blob's size (an empty file may represent a downloaded ADLS Gen2 directory); if the stat fails — path missing, permission denied, or filesystem error — this wrapped error is returned.","triggerScenarios":"The downloaded file disappeared between download and stat (race, cleanup), the mount holding the artifact path is read-only or full, or the executor lacks permission to stat the file it just wrote on a volume with restrictive permissions.","commonSituations":"Running with securityContext that restricts filesystem access on the emptyDir/hostPath artifact volume; node disk pressure; a security scanner or sidecar deleting files in the artifacts directory mid-workflow.","solutions":["Inspect the wrapped lstatErr cause to identify ENOENT vs EACCES vs EIO.","Check the artifact path volume is writable and not concurrently cleaned (no conflicting sidecars/scanners).","Re-run the workflow — a transient node/filesystem issue often resolves on retry.","Verify securityContext/fsGroup settings allow the executor user to stat files under /tmp (or the configured artifact path)."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// ensure the artifact dir is writable before download:\nif err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { return err }\nif f, err := os.CreateTemp(filepath.Dir(path), \".probe\"); err == nil { f.Close(); os.Remove(f.Name()) }","typeGuard":null,"tryCatchPattern":"if err := DownloadFile(ctx, client, blob, path); err == nil {\n\t_, lstatErr := os.Lstat(path)\n\tif lstatErr != nil {\n\t\tif os.IsNotExist(lstatErr) || os.IsPermission(lstatErr) {\n\t\t\treturn retryDownload(ctx, client, blob, path) // transient/perm issue\n\t\t}\n\t\treturn fmt.Errorf(\"lstat %s: %w\", path, lstatErr)\n\t}\n}","preventionTips":["Keep artifact volumes writable and sized adequately; avoid read-only mounts for output paths.","Don't run sidecars/scanners that clean the artifact directory during execution.","Set fsGroup/securityContext so the executor user owns downloaded files."],"tags":["azure","filesystem","artifacts"],"backgroundTag":"file-stat-failed","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"}