kubernetes/kops · error
error moving downloaded file %q to %q: %v
Error message
error moving downloaded file %q to %q: %v
What it means
The final step makes the download atomic: the temp file is renamed over the destination path. If os.Rename fails, this error reports both the temp path and the destination. This guarantees partial downloads never replace a good file.
Source
Thrown at upup/pkg/fi/http.go:77
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))
}()
klog.V(2).Infof("Downloading %q", desturl)
View on GitHub (pinned to 4c8573c808)
Solutions
- Check the wrapped %v error (EXDEV, ENOENT, EACCES etc.)
- Verify the destination directory still exists and is writable
- Remove any directory occupying the destination path
- Re-run the download
Example fix
// before: /path/to/file is actually a directory rm -rf /path/to/file // after: re-run kops apply to retry the download
Defensive patterns
Strategy: try-catch
Validate before calling
if info, err := os.Lstat(destPath); err == nil && info.IsDir() {
return fmt.Errorf("destination %s is a directory", destPath)
} Try / catch
if _, err := fi.DownloadURL(ctx, url, dest, nil); err != nil {
var le *os.LinkError
if errors.As(err, &le) {
log.Printf("rename failed: %v -> %v: %v", le.Old, le.New, le.Err)
}
return err
} Prevention
- Never place a directory where the destination file is expected
- Avoid unmounting or deleting download directories mid-operation
- Keep the download destination stable across runs
When it happens
Trigger: os.Rename(tempPath, destPath) fails: cross-device link (temp and dest on different filesystems — not possible here since temp is in the same dir), dest directory removed mid-flight, or permission problems.
Common situations: Destination directory deleted or unmounted during download; a directory exists at destPath; antivirus/cleanup tooling interfering with .tmp files.
Related errors
- error renaming extracted temp dir %s -> %s: %v
- error creating directories for destination file %q: %v
- error creating temporary file for download %q: %v
- error setting mode on downloaded file %q: %v
- error during file write of %q: rename failed: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/4e559da1048deda0.
Report an issue: GitHub.