kubernetes/kops · error

error creating sftp client (in new-session): %w

Error message

error creating sftp client (in new-session): %w

What it means

SSHPath.newClient in util/pkg/vfs/sshfs.go wraps errors from p.client.NewSession() with this message when the sudo=true path tries to open a new SSH session to run `sudo /usr/lib/openssh/sftp-server`. It means the SSH connection exists but a new session channel could not be opened — commonly because the server hit the session limit, the connection dropped, or the server refuses session channels for this user.

Source

Thrown at util/pkg/vfs/sshfs.go:67

		client: client,
		server: server,
		path:   path,
		sudo:   sudo,
	}
}

func (p *SSHPath) newClient(ctx context.Context) (*sftp.Client, error) {
	if !p.sudo {
		sftpClient, err := sftp.NewClient(p.client)
		if err != nil {
			return nil, fmt.Errorf("error creating sftp client: %w", err)
		}

		return sftpClient, nil
	}
	s, err := p.client.NewSession()
	if err != nil {
		return nil, fmt.Errorf("error creating sftp client (in new-session): %w", err)
	}

	stdin, err := s.StdinPipe()
	if err != nil {
		return nil, fmt.Errorf("error creating sftp client (at stdin pipe): %w", err)
	}
	stdout, err := s.StdoutPipe()
	if err != nil {
		return nil, fmt.Errorf("error creating sftp client (at stdout pipe): %w", err)
	}

	err = s.Start("sudo /usr/lib/openssh/sftp-server")
	if err != nil {
		return nil, fmt.Errorf("error creating sftp client (executing 'sudo /usr/lib/openssh/sftp-server'): %w", err)
	}

	c, err := sftp.NewClientPipe(stdout, stdin)
	if err != nil {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Raise MaxSessions in the remote sshd_config and reload sshd
  2. Re-establish the ssh.Client and retry — the existing one is likely stale or closed
  3. Check for NAT/firewall idle timeouts; enable SSH keepalives on the client
  4. Verify the account is permitted to open session channels (not restricted to a single forced command)

Example fix

// before (server sshd_config)
MaxSessions 1
// after
MaxSessions 10
# then: sudo systemctl reload sshd
Defensive patterns

Strategy: retry

Validate before calling

// check MaxSessions reachability before VFS use
s, err := client.NewSession()
if err != nil {
	log.Fatalf("cannot open ssh session to %s: %v (check sshd MaxSessions)", host, err)
}
s.Close()

Type guard

func isSSHSessionError(err error) bool {
	return err != nil && strings.Contains(err.Error(), "sftp client (in new-session)")
}

Try / catch

err := p.WriteFile(ctx, data, acl)
if err != nil && strings.Contains(err.Error(), "error creating sftp client (in new-session)") {
	// stale/limited connection: re-dial and retry once
	client, derr := ssh.Dial("tcp", host, cfg)
	if derr == nil {
		p = vfs.NewSSHPath(client, host, path, true)
		return p.WriteFile(ctx, data, acl)
	}
}
return err

Prevention

When it happens

Trigger: Any SSHPath operation with sudo=true where client.NewSession() fails: sshd MaxSessions exhausted (each operation opens a new session), connection closed by the remote host, or the ssh.Client is stale after an idle timeout or network change.

Common situations: Using an ssh:// VFS with sudo=true against a node whose sshd limits sessions (MaxSessions=1 or low); firewall/NAT dropping idle SSH connections; connecting with a client that was closed elsewhere; restricted accounts with session channel limits.

Related errors


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