hashicorp/terraform · error
timeout - last error
Error message
timeout - last error: %v
What it means
Surfaced by the communicator Retry loop when the connection block's timeout elapsed (context.DeadlineExceeded) before a successful connection/command. The %v carries the last retryable error. This reflects the connection { timeout = "..." } setting, not the overall Terraform operation timeout.
Solutions
- Increase connection.timeout (e.g. timeout = "15m") if the host genuinely needs more startup time.
- Fix the last error in %v: verify host, port, user, private_key/password, and that the security group allows ingress.
- Add a remote_task / provisioner 'local-exec' health gate or use depends_on with a readiness check so the host is up before remote-exec runs.
- For AWS, confirm the instance is running and its public_ip is set (use aws_instance.public_ip, not a static value).
Example fix
// before
connection {
host = aws_instance.web.public_ip
user = "ubuntu"
private_key = file("~/.ssh/id_rsa")
}
// after
connection {
host = aws_instance.web.public_ip
user = "ubuntu"
private_key = file("~/.ssh/id_rsa")
timeout = "15m"
} Defensive patterns
Strategy: retry
Validate before calling
// Before apply, sanity-check that the host is reachable and creds are valid:
// $ nc -vz <host> 22 (or 5985/5986 for winrm)
// $ ssh -i <key> <user>@<host> true (smoke test)
// In HCL, set a generous timeout for freshly-booted hosts:
// connection { timeout = "15m" } Try / catch
// In Go, treat a timeout as retryable at the orchestration layer only if
// the host may still come up; otherwise fail fast:
if errors.Is(err, context.DeadlineExceeded) || strings.Contains(err.Error(), "timeout - last error") {
return fmt.Errorf("provisioner timed out; verify host/creds/sg: %w", err)
} Prevention
- Set connection.timeout generously for new instances (10-15m).
- Use a readiness gate (local-exec health check, or depends_on) before remote-exec.
- Confirm security group ingress and correct user/key before running apply.
When it happens
Trigger: A provisioner/connection that never succeeds within the configured timeout (default 5 minutes) because the host is unreachable, credentials fail, or the service is not up. Each retry hit the same failure until the deadline expired.
Common situations: Newly-created instance not yet accepting SSH (cloud-init/user-data still running); wrong host/IP in connection block; security group or NACL blocking the port; wrong user or key; winrm/HTTPS listener not ready on Windows AMIs.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- connection type ' ' not supported
- Error connecting to bastion
- Error connecting to proxy
- host for provisioner cannot be empty
- interrupted - last error
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/2f37bd5e2a272004.
Report an issue: GitHub.
Appendix: source
Thrown at internal/communicator/communicator.go:166
// Wait for completion
select {
case <-ctx.Done():
case <-doneCh:
}
var lastErr error
// Check if we got an error executing
if ev, ok := errVal.Load().(errWrap); ok {
lastErr = ev.E
}
// Check if we have a context error to check if we're interrupted or timeout
switch ctx.Err() {
case context.Canceled:
return fmt.Errorf("interrupted - last error: %v", lastErr)
case context.DeadlineExceeded:
return fmt.Errorf("timeout - last error: %v", lastErr)
}
if lastErr != nil {
return lastErr
}
return nil
}
View on GitHub (pinned to d32a084675)