{"record":{"id":"8ddf8f1f05f53fbf","repo":"kubernetes/kops","slug":"error-setting-mode-on-downloaded-file-q-v","errorCode":null,"errorMessage":"error setting mode on downloaded file %q: %v","messagePattern":"error setting mode on downloaded file %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/http.go","lineNumber":74,"sourceCode":"\t\treturn nil, fmt.Errorf(\"error creating directories for destination file %q: %v\", destPath, err)\n\t}\n\n\toutput, err := os.CreateTemp(dir, \".\"+filepath.Base(destPath)+\".tmp\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error creating temporary file for download %q: %v\", destPath, err)\n\t}\n\ttempPath := output.Name()\n\tdefer os.Remove(tempPath)\n\n\tactual, err := downloadURLToWriter(ctx, url, output, hash)\n\tif closeErr := output.Close(); closeErr != nil && err == nil {\n\t\terr = closeErr\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err := os.Chmod(tempPath, 0o644); err != nil {\n\t\treturn nil, fmt.Errorf(\"error setting mode on downloaded file %q: %v\", tempPath, err)\n\t}\n\tif err := os.Rename(tempPath, destPath); err != nil {\n\t\treturn nil, fmt.Errorf(\"error moving downloaded file %q to %q: %v\", tempPath, destPath, err)\n\t}\n\treturn actual, nil\n}\n\n// downloadURLToWriter streams the file at the given url to dest.\n// If hash is non-nil, it will also verify that it matches the downloaded bytes.\nfunc downloadURLToWriter(ctx context.Context, desturl string, dest io.Writer, hash *hashing.Hash) (*hashing.Hash, error) {\n\tu, err := url.Parse(desturl)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"Invalud URL for file %q: %v\", desturl, err)\n\t}\n\n\tstart := time.Now()\n\tdefer func() {\n\t\tklog.V(2).Infof(\"Downloading %q took %q\", desturl, time.Since(start))","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/http.go#L56-L92","documentation":"After a successful download, the temp file is chmod'ed to 0o644 before being renamed into place. If the chmod fails (rare; the file was just created by the same process), the error is wrapped with this message.","triggerScenarios":"os.Chmod(tempPath, 0o644) returns an error, typically due to filesystem restrictions (e.g. on certain network/overlay mounts) or the temp file having been removed concurrently.","commonSituations":"Downloading to a filesystem that disallows chmod (some NFS/CIFS mounts, certain container volume drivers); temp file vanished due to a cleaner process.","solutions":["Read the wrapped %v error to identify the chmod failure reason","Download to a local filesystem that supports permission changes","Ensure no cleanup job removes .*.tmp files concurrently","Retry the download after fixing the target filesystem"],"exampleFix":"// before: dest on mount without chmod support\nDownloadURL(..., \"/mnt/cifs/kops/...\")\n// after\nDownloadURL(..., \"/var/lib/kops/...\")  # local ext4/overlayfs","handlingStrategy":"retry","validationCode":"// Verify target filesystem supports chmod\nif err := os.Chmod(dir, 0o755); err != nil {\n    return fmt.Errorf(\"filesystem %s does not support chmod: %w\", dir, err)\n}","typeGuard":null,"tryCatchPattern":"if _, err := fi.DownloadURL(ctx, url, dest, nil); err != nil {\n    if strings.Contains(err.Error(), \"error setting mode\") {\n        // transient fs issue; retry or relocate destination\n        return retryDownload(ctx, url, localDest)\n    }\n    return err\n}","preventionTips":["Download to local filesystems, not NFS/CIFS shares that restrict chmod","Exclude kops download dirs from aggressive cleanup tooling","Use standard Linux volumes for asset caches"],"tags":["filesystem","permissions","download"],"backgroundTag":"chmod-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}