{"record":{"id":"2f37bd5e2a272004","repo":"hashicorp/terraform","slug":"timeout-last-error-v","errorCode":null,"errorMessage":"timeout - last error: %v","messagePattern":"timeout - last error: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/communicator/communicator.go","lineNumber":166,"sourceCode":"\n\t// Wait for completion\n\tselect {\n\tcase <-ctx.Done():\n\tcase <-doneCh:\n\t}\n\n\tvar lastErr error\n\t// Check if we got an error executing\n\tif ev, ok := errVal.Load().(errWrap); ok {\n\t\tlastErr = ev.E\n\t}\n\n\t// Check if we have a context error to check if we're interrupted or timeout\n\tswitch ctx.Err() {\n\tcase context.Canceled:\n\t\treturn fmt.Errorf(\"interrupted - last error: %v\", lastErr)\n\tcase context.DeadlineExceeded:\n\t\treturn fmt.Errorf(\"timeout - last error: %v\", lastErr)\n\t}\n\n\tif lastErr != nil {\n\t\treturn lastErr\n\t}\n\treturn nil\n}\n","sourceCodeStart":148,"sourceCodeEnd":174,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/communicator/communicator.go#L148-L174","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\nconnection {\n  host        = aws_instance.web.public_ip\n  user        = \"ubuntu\"\n  private_key = file(\"~/.ssh/id_rsa\")\n}\n\n// after\nconnection {\n  host        = aws_instance.web.public_ip\n  user        = \"ubuntu\"\n  private_key = file(\"~/.ssh/id_rsa\")\n  timeout     = \"15m\"\n}","handlingStrategy":"retry","validationCode":"// Before apply, sanity-check that the host is reachable and creds are valid:\n//   $ nc -vz <host> 22  (or 5985/5986 for winrm)\n//   $ ssh -i <key> <user>@<host> true   (smoke test)\n// In HCL, set a generous timeout for freshly-booted hosts:\n// connection { timeout = \"15m\" }","typeGuard":null,"tryCatchPattern":"// In Go, treat a timeout as retryable at the orchestration layer only if\n// the host may still come up; otherwise fail fast:\nif errors.Is(err, context.DeadlineExceeded) || strings.Contains(err.Error(), \"timeout - last error\") {\n    return fmt.Errorf(\"provisioner timed out; verify host/creds/sg: %w\", err)\n}","preventionTips":["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."],"tags":["terraform","connection","timeout","retry","ssh","provisioner"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}