kubernetes/kops · error
renaming file %q -> %q (with %q): %w
Error message
renaming file %q -> %q (with %q): %w
What it means
The non-posix fallback renames the temp file by running a shell command (`mv tempfile p.path`, prefixed with `sudo` if p.sudo is set) through session.Run. If the command exits non-zero, this error wraps the failure and includes the exact command executed. Causes include permission denied, missing mv, or remote disk issues.
Source
Thrown at util/pkg/vfs/sshfs.go:260
}
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
}
if err := session.Run(cmd); err != nil {
return fmt.Errorf("renaming file %q -> %q (with %q): %w", tempfile, p.path, cmd, err)
}
deleteTempFile = false
}
return nil
}
// To prevent concurrent creates on the same file while maintaining atomicity of writes,
// we take a process-wide lock during the operation.
// Not a great approach, but fine for a single process (with low concurrency)
var createFileLockSSH sync.Mutex
func (p *SSHPath) CreateFile(ctx context.Context, data io.ReadSeeker, acl ACL) error {
createFileLockSSH.Lock()
defer createFileLockSSH.Unlock()
// Check if exists
_, err := p.ReadFile(ctx)View on GitHub (pinned to 4c8573c808)
Solutions
- If permission is the issue, construct the SSHPath with sudo enabled: vfs.NewSSHPath(client, server, path, true), and ensure the user has passwordless sudo for mv (NOPASSWD in sudoers).
- Remove 'requiretty' and any password prompt for the automation user in /etc/sudoers so non-interactive `sudo mv` works.
- Manually test the exact command from the error message via SSH to see the underlying output.
- Verify `mv` exists in the default PATH for non-interactive sessions; use an absolute path (/bin/mv) if the PATH is minimal.
Example fix
// before: sudoers prompts for password, session.Run fails sftpuser ALL=(ALL) ALL // after sftpuser ALL=(ALL) NOPASSWD: /bin/mv
Defensive patterns
Strategy: validation
Validate before calling
// confirm passwordless sudo mv works non-interactively before relying on it out := sshRun(host, "sudo -n true && echo sudo-ok") // require "sudo-ok"
Try / catch
err := path.WriteFile(ctx, data, acl)
if err != nil && strings.Contains(err.Error(), "renaming file") {
return fmt.Errorf("remote mv failed; run the quoted command manually via ssh to see the real output: %w", err)
} Prevention
- Grant the automation user NOPASSWD sudo limited to /bin/mv (or required paths).
- Remove Defaults requiretty from sudoers for non-interactive automation.
- Prefer the posix-rename path (default) to avoid shell/sudo entirely.
- Test the exact mv command quoted in the error over an interactive SSH session.
When it happens
Trigger: session.Run("mv ...") returns non-zero: the SSH user lacks permission on either path (and p.sudo is false so no sudo was used), sudo requires a password/TTY, the shell is restricted, or the target directory vanished.
Common situations: Writing to root-owned directories without sudo on the SSHPath; sudoers requiring a TTY (requiretty) or password for the automation user; restricted rbash on bastion hosts; read-only root filesystem.
Related errors
- error creating directory %q over sftp: %w
- error during chmod of %q: %w
- removing destination sftp file %q before rename: %w
- renaming sftp file %q -> %q (with posix rename): %w
- creating session for rename: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/59ffbe120e2901d1.
Report an issue: GitHub.