kubernetes/kops · error
error writing script to SSH target: %w
Error message
error writing script to SSH target: %w
What it means
runScript writes the shell script to scriptPath on the remote host using a vfs SSH path writer. If p.WriteFile fails — session I/O error, permission denied (root-owned dir), or disk full — this error wraps it; the deferred cleanup removes the temp dir either way.
Source
Thrown at pkg/commands/toolbox_enroll.go:370
b := make([]byte, 32)
if _, err := cryptorand.Read(b); err != nil {
return nil, fmt.Errorf("error getting random data: %w", err)
}
tempDir = path.Join("/tmp", hex.EncodeToString(b))
}
scriptPath := path.Join(tempDir, "script.sh")
p := vfs.NewSSHPath(s.sshClient, s.hostname, scriptPath, s.sudo)
defer func() {
if _, err := s.runCommand(ctx, "rm -rf "+tempDir, ExecOptions{Echo: false}); err != nil {
klog.Warningf("error cleaning up temp directory %q: %v", tempDir, err)
}
}()
if err := p.WriteFile(ctx, bytes.NewReader([]byte(script)), nil); err != nil {
return nil, fmt.Errorf("error writing script to SSH target: %w", err)
}
scriptCommand := "/bin/bash " + scriptPath
return s.runCommand(ctx, scriptCommand, options)
}
// CommandOutput holds the results of running a command.
type CommandOutput struct {
Stdout bytes.Buffer
Stderr bytes.Buffer
}
// ExecOptions holds options for running a command remotely.
type ExecOptions struct {
Echo bool
}
func (s *SSHHost) runCommand(ctx context.Context, command string, options ExecOptions) (*CommandOutput, error) {View on GitHub (pinned to 4c8573c808)
Solutions
- Read the wrapped error: 'permission denied' → ensure passwordless sudo for the SSH user (visudo)
- Check remote /tmp: df -h /tmp and mount | grep /tmp (watch for noexec/nosuid restrictions)
- Verify network stability and retry enroll
- Manually test the equivalent: ssh <user>@<host> 'mkdir -p /tmp/test && echo ok > /tmp/test/f'
Example fix
// before $ kops toolbox enroll ... Error: error writing script to SSH target: mkdir /tmp/abc...: permission denied // after $ ssh admin@node 'sudo visudo' # add: admin ALL=(ALL) NOPASSWD:ALL $ df -h /tmp # ensure space, and /tmp not mounted noexec $ kops toolbox enroll ...
Defensive patterns
Strategy: validation
Validate before calling
if err := exec.Command("ssh", user+"@"+host,
"test -w /tmp && [ $(df -k --output=avail /tmp | tail -1) -gt 10240 ]").Run(); err != nil {
return fmt.Errorf("remote /tmp not writable or <10MB free")
} Type guard
func remoteTmpWritable(ctx context.Context, h *SSHHost) bool {
_, err := h.runCommand(ctx, "test -w /tmp", ExecOptions{Echo: false})
return err == nil
} Try / catch
_, err := sshTarget.runScript(ctx, script, ExecOptions{Echo: true})
if err != nil {
if strings.Contains(err.Error(), "error writing script to SSH target") {
return fmt.Errorf("check remote /tmp permissions and free space: %w", err)
}
return err
} Prevention
- Ensure the SSH user has passwordless sudo for staging under /tmp
- Verify /tmp is writable and has free space on target nodes
- Retry on transient network drops; check mount flags (noexec) if exec fails next
When it happens
Trigger: p.WriteFile(ctx, bytes.NewReader([]byte(script)), nil) fails: SSH session dropped mid-write, /tmp not writable, noexec/no-space /tmp, or sudo wrapping failing so the write cannot create directories under /tmp.
Common situations: Remote /tmp mounted noexec or full; enroll run against a host whose SSH user lacks sudo rights to create the temp dir; long-running script staging interrupted by network flaps.
Related errors
- method DeleteSSHCredential not supported in server-side clie
- method AddSSHPublicKey not supported in server-side client
- must specify %q label with cluster name to create SSHCredent
- spec.PublicKey is required
- error reading SSH key file %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/f053895bd80fa607.
Report an issue: GitHub.