hashicorp/terraform · error

Error connecting to bastion

Error message

Error connecting to bastion: %s

What it means

Returned when neither the proxy-via-bastion path nor the direct ssh.Dial to the bastion succeeded — the umbrella error after both branches. With a proxy configured it fires if bastion.Dial failed despite a successful NewClientConn; without a proxy it fires if the direct ssh.Dial to the bastion failed. It indicates the bastion itself is the problem, not the proxy.

Solutions

  1. Confirm network reachability to the bastion: nc -vz <bastion_host> <bastion_port>.
  2. Verify bastion_host and bastion_port (default 22) values.
  3. Open the security group / firewall for ingress to the bastion from the runner's IP.
  4. Read the wrapped %s to distinguish auth failure vs connection refused vs host key mismatch.

Example fix

// before
connection {
  host          = "10.0.0.5"
  bastion_host  = "bastion.exmaple.com" // typo
  bastion_port  = 2222
}

// after
connection {
  host          = "10.0.0.5"
  bastion_host  = "bastion.example.com"
  bastion_port  = 22
}
Defensive patterns

Strategy: validation

Validate before calling

# Verify reachability to the bastion before apply:
#   nc -vz <bastion_host> <bastion_port>
# Confirm security groups/firewalls allow the runner -> bastion on that port.

Try / catch

// In Go, the umbrella bastion error wraps the actual dial failure; surface it:
if strings.Contains(err.Error(), "Error connecting to bastion") {
    return fmt.Errorf("bastion unreachable; check host/port/sg: %w", err)
}

Prevention

When it happens

Trigger: Direct (no-proxy) SSH dial to bastion_host:bastion_port failed (network, host key, auth), OR with a proxy the bastion connection opened but bastion.Dial to dial further failed. The wrapped %s gives the ssh.Dial or bastion.Dial error.

Common situations: bastion_host typo or wrong bastion_port; security group/ACL blocking the bastion port from the runner; bastion sshd down; host key changed; network partition to the bastion.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/429eae90a2c14c29. Report an issue: GitHub.

Appendix: source

Thrown at internal/communicator/ssh/communicator.go:861

			pConn, err = newHttpProxyConn(p, bAddr)

			if err != nil {
				return nil, fmt.Errorf("Error connecting to proxy: %s", err)
			}

			bConn, bChans, bReq, err = ssh.NewClientConn(pConn, bAddr, bConf)

			if err != nil {
				return nil, fmt.Errorf("Error creating new client connection via proxy: %s", err)
			}

			bastion = ssh.NewClient(bConn, bChans, bReq)
		} else {
			bastion, err = ssh.Dial(bProto, bAddr, bConf)
		}

		if err != nil {
			return nil, fmt.Errorf("Error connecting to bastion: %s", err)
		}

		log.Printf("[DEBUG] Connecting via bastion (%s) to host: %s", bAddr, addr)
		conn, err := bastion.Dial(proto, addr)
		if err != nil {
			bastion.Close()
			return nil, err
		}

		// Wrap it up so we close both things properly
		return &bastionConn{
			Conn:    conn,
			Bastion: bastion,
		}, nil
	}
}

type bastionConn struct {

View on GitHub (pinned to d32a084675)