kubernetes/kops · error
removing destination sftp file %q before rename: %w
Error message
removing destination sftp file %q before rename: %w
What it means
Because POSIX-rename via SFTP fails when the destination exists, WriteFile first removes the destination file p.path. If Remove fails with anything other than NotExist, this error wraps the cause. It means the old file could not be cleared, so the atomic rename was not attempted.
Source
Thrown at util/pkg/vfs/sshfs.go:240
if !ok {
return fmt.Errorf("unexpected acl type %T", acl)
} else {
err = sftpClient.Chmod(tempfile, sshACL.Mode)
if err != nil {
return fmt.Errorf("error during chmod of %q: %w", tempfile, err)
}
}
}
// posix rename will replace the destination (normal sftp rename does not)
usePosixRename := true
if usePosixRename {
// posix rename fails if destination exists, try to delete just in case
if err := sftpClient.Remove(p.path); err != nil {
if os.IsNotExist(err) {
// expected when file does not exist already
} else {
return fmt.Errorf("removing destination sftp file %q before rename: %w", p.path, err)
}
}
if err := sftpClient.Rename(tempfile, p.path); err != nil {
return fmt.Errorf("renaming sftp file %q -> %q (with posix rename): %w", tempfile, p.path, err)
}
deleteTempFile = false
} else {
var session *ssh.Session
session, err = p.client.NewSession()
if err != nil {
return fmt.Errorf("creating session for rename: %w", err)
}
defer session.Close()
cmd := "mv " + tempfile + " " + p.path
if p.sudo {
cmd = "sudo " + cmd
}View on GitHub (pinned to 4c8573c808)
Solutions
- SSH to the host and remove/fix ownership of the destination: `sudo rm <path>` or `sudo chown <sftpuser> <dir>`.
- Grant the SFTP user write permission on the destination directory (directory write permission, not file ownership, is what Remove needs).
- Check for immutable flags: `lsattr <path>` and `sudo chattr -i <path>` if set.
- Retry if the wrapped error indicates a transient connection issue.
Example fix
// before: /etc/kubernetes/manifests owned by root, sftp user cannot delete $ ssh host 'sudo chown -R sftpuser:sftpuser /etc/kubernetes/manifests' // after: retry kops write — destination removal succeeds
Defensive patterns
Strategy: validation
Validate before calling
// destination removal needs write permission on the directory
out := sshRun(host, fmt.Sprintf("test -w %s && echo dir-writable", path.Dir(dest))) Try / catch
err := path.WriteFile(ctx, data, acl)
if err != nil {
var permErr *fs.PathError
if strings.Contains(err.Error(), "removing destination sftp file") {
// escalate ownership on the remote dir, then retry
sshRun(host, fmt.Sprintf("sudo chown %s %s", sftpUser, path.Dir(dest)))
return path.WriteFile(ctx, data, acl)
}
_ = permErr
return err
} Prevention
- Give the SFTP user write permission on directories whose files will be overwritten.
- Avoid chattr +i and root-only ownership on kOps-managed files.
- Stop competing writers before overwriting managed manifests.
When it happens
Trigger: sftpClient.Remove(p.path) fails with EACCES/EPERM (no write permission on the directory containing the destination), EBUSY, or a connection error — i.e. the destination exists but cannot be deleted.
Common situations: Overwriting an existing file on a host where the SFTP user lacks directory write permission (file owned by root); destination directory has sticky bit and different owner; immutable attribute (chattr +i) on the file.
Related errors
- error creating directory %q over sftp: %w
- error during chmod of %q: %w
- error creating sftp client: %w
- error creating sftp client (in new-session): %w
- error creating sftp client (at stdin pipe): %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/3f8fcb4649e52d6a.
Report an issue: GitHub.