kubernetes/kops · error

error setting mode on downloaded file %q: %v

Error message

error setting mode on downloaded file %q: %v

What it means

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.

Source

Thrown at upup/pkg/fi/http.go:74

		return nil, fmt.Errorf("error creating directories for destination file %q: %v", destPath, err)
	}

	output, err := os.CreateTemp(dir, "."+filepath.Base(destPath)+".tmp")
	if err != nil {
		return nil, fmt.Errorf("error creating temporary file for download %q: %v", destPath, err)
	}
	tempPath := output.Name()
	defer os.Remove(tempPath)

	actual, err := downloadURLToWriter(ctx, url, output, hash)
	if closeErr := output.Close(); closeErr != nil && err == nil {
		err = closeErr
	}
	if err != nil {
		return nil, err
	}
	if err := os.Chmod(tempPath, 0o644); err != nil {
		return nil, fmt.Errorf("error setting mode on downloaded file %q: %v", tempPath, err)
	}
	if err := os.Rename(tempPath, destPath); err != nil {
		return nil, fmt.Errorf("error moving downloaded file %q to %q: %v", tempPath, destPath, err)
	}
	return actual, nil
}

// downloadURLToWriter streams the file at the given url to dest.
// If hash is non-nil, it will also verify that it matches the downloaded bytes.
func downloadURLToWriter(ctx context.Context, desturl string, dest io.Writer, hash *hashing.Hash) (*hashing.Hash, error) {
	u, err := url.Parse(desturl)
	if err != nil {
		return nil, fmt.Errorf("Invalud URL for file %q: %v", desturl, err)
	}

	start := time.Now()
	defer func() {
		klog.V(2).Infof("Downloading %q took %q", desturl, time.Since(start))

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Read the wrapped %v error to identify the chmod failure reason
  2. Download to a local filesystem that supports permission changes
  3. Ensure no cleanup job removes .*.tmp files concurrently
  4. Retry the download after fixing the target filesystem

Example fix

// before: dest on mount without chmod support
DownloadURL(..., "/mnt/cifs/kops/...")
// after
DownloadURL(..., "/var/lib/kops/...")  # local ext4/overlayfs
Defensive patterns

Strategy: retry

Validate before calling

// Verify target filesystem supports chmod
if err := os.Chmod(dir, 0o755); err != nil {
    return fmt.Errorf("filesystem %s does not support chmod: %w", dir, err)
}

Try / catch

if _, err := fi.DownloadURL(ctx, url, dest, nil); err != nil {
    if strings.Contains(err.Error(), "error setting mode") {
        // transient fs issue; retry or relocate destination
        return retryDownload(ctx, url, localDest)
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: Downloading to a filesystem that disallows chmod (some NFS/CIFS mounts, certain container volume drivers); temp file vanished due to a cleaner process.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/8ddf8f1f05f53fbf. Report an issue: GitHub.