kubernetes/kops · error
creating ssh session: %w
Error message
creating ssh session: %w
What it means
After forwarding the agent, Dial opens an SSH session on the bastion connection with client.NewSession(); failure is reported to the finished channel wrapped with this message. The error means the SSH client connection exists but a new session channel could not be created — usually because the connection dropped or the server rejected the session.
Source
Thrown at pkg/dump/dumper.go:712
var client *ssh.Client
finished := make(chan error)
go func() {
c, chans, reqs, err := ssh.NewClientConn(conn, addr, f.sshConfig)
if err == nil {
client = ssh.NewClient(c, chans, reqs)
if useBastion {
err = agent.ForwardToAgent(client, f.keyRing)
if err != nil {
err = fmt.Errorf("forwarding ssh auth to keyring: %w", err)
}
}
}
if err == nil && useBastion {
session, err := client.NewSession()
if err != nil {
finished <- fmt.Errorf("creating ssh session: %w", err)
return
}
defer session.Close()
err = agent.RequestAgentForwarding(session)
if err != nil {
finished <- fmt.Errorf("requesting agent forwarding: %w", err)
return
}
}
finished <- err
}()
select {
case <-ctx.Done():
klog.Infof("cancelling SSH tcp connection due to context completion")
conn.Close() // Close the TCP connection to force cancellationView on GitHub (pinned to 4c8573c808)
Solutions
- Retry the Dial after confirming the bastion is healthy (ssh user@bastion works)
- Reduce concurrent SSH sessions to the bastion or raise sshd MaxSessions on the bastion host
- Check bastion sshd logs and instance state; recreate the bastion instance if it is wedged
- Increase context timeout / add backoff-retry around the dump operation for transient drops
Example fix
// before
client, err := factory.Dial(ctx, host, true)
// after
var client sshClient
err = wait.PollImmediate(5*time.Second, 2*time.Minute, func() (bool, error) {
var e error
client, e = factory.Dial(ctx, host, true)
return e == nil, nil
}) Defensive patterns
Strategy: retry
Validate before calling
var ok bool
for i := 0; i < 3; i++ {
c, e := net.DialTimeout("tcp", net.JoinHostPort(bastion, "22"), 3*time.Second)
if e == nil {
c.Close()
ok = true
break
}
time.Sleep(2 * time.Second)
}
if !ok {
return fmt.Errorf("bastion %s not accepting sessions", bastion)
} Type guard
func isSessionError(err error) bool { return strings.Contains(err.Error(), "creating ssh session") } Try / catch
client, err := factory.Dial(ctx, host, true)
if err != nil && strings.Contains(err.Error(), "creating ssh session") {
// transient: back off and retry
time.Sleep(5 * time.Second)
client, err = factory.Dial(ctx, host, true)
} Prevention
- Limit concurrent SSH sessions to the bastion or raise sshd MaxSessions
- Add retry with backoff around Dial for transient session failures
- Monitor bastion health (instance status, sshd) before bulk dumps
When it happens
Trigger: client.NewSession() fails inside the Dial goroutine when useBastion=true, after ForwardToAgent succeeded — connection to bastion reset/closed, server-side session limits (MaxSessions), or server refusing new channels.
Common situations: Bastion sshd hitting MaxSessions limits during concurrent dumps; bastion restarting mid-dump; sshd config restricting session channels; transient network interruption right after handshake.
Related errors
- error creating ssh session: %v
- bastion is not set, but useBastion is true
- forwarding ssh auth to keyring: %w
- bastion not healthy after update, stopping rolling-update: %
- creating session for rename: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/b22ff54cf39880ae.
Report an issue: GitHub.