hashicorp/terraform · error
ssh client is not connected
Error message
ssh client is not connected
What it means
Returned by the SSH `Communicator.newSession` when `c.client` is nil, i.e. a session is requested before `Connect` has established the underlying `*ssh.Client`. The function then attempts an automatic reconnect and retries, so this error only escapes to the caller if the reconnect also fails.
Solutions
- Ensure `Communicator.Connect()` succeeds before issuing file/upload/command operations.
- Check the SSH host, port, and credentials in the connection block; verify reachability with `ssh` directly.
- If intermittent, raise retries/timeout on the connection; the built-in reconnect only fires once.
Defensive patterns
Strategy: retry
Validate before calling
// Ensure the client is connected before opening a session:
if c.client == nil {
if err := c.Connect(nil); err != nil {
return nil, fmt.Errorf("ssh not connected: %w", err)
}
} Type guard
// sshReady reports whether the communicator can open a session right now.
func sshReady(c *Communicator) bool { return c.client != nil } Try / catch
session, err := comm.newSession()
if err != nil && strings.Contains(err.Error(), "ssh client is not connected") {
if cerr := comm.Connect(nil); cerr != nil { return cerr }
session, err = comm.newSession()
} Prevention
- Call Connect explicitly and check its error before any upload/command.
- Verify SSH host/port/credentials in the connection block before provisioning.
- Build reconnect-with-backoff around flaky hosts rather than relying on the single built-in retry.
When it happens
Trigger: `newSession()` is called while `c.client == nil` (never connected, or connection was torn down) and the fallback `c.Connect(nil)` also fails.
Common situations: Provisioner tries to open a session before the first `Connect`; the SSH connection was dropped and reconnect fails (network, host down, auth changed); misordered communicator lifecycle in a custom provisioner.
Related errors
- connection type ' ' not supported
- Error connecting to bastion
- Error connecting to proxy
- Failed to read ssh private key: no key found
- Failed to read ssh private key: password protected keys…
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/f646c9800603d4fa.
Report an issue: GitHub.
Appendix: source
Thrown at internal/communicator/ssh/communicator.go:522
if src[len(src)-1] != '/' {
log.Printf("[DEBUG] No trailing slash, creating the source directory name")
return scpUploadDirProtocol(filepath.Base(src), w, r, uploadEntries)
}
// Trailing slash, so only upload the contents
return uploadEntries()
}
cmd, err := quoteScpCommand([]string{"scp", "-rvt", dst}, c.connInfo.TargetPlatform)
if err != nil {
return err
}
return c.scpSession(cmd, scpFunc)
}
func (c *Communicator) newSession() (session *ssh.Session, err error) {
log.Println("[DEBUG] opening new ssh session")
if c.client == nil {
err = errors.New("ssh client is not connected")
} else {
session, err = c.client.NewSession()
}
if err != nil {
log.Printf("[WARN] ssh session open error: '%s', attempting reconnect", err)
if err := c.Connect(nil); err != nil {
return nil, err
}
return c.client.NewSession()
}
return session, nil
}
func (c *Communicator) scpSession(scpCommand string, f func(io.Writer, *bufio.Reader) error) error {
session, err := c.newSession()View on GitHub (pinned to d32a084675)