{"record":{"id":"a11ff432e51cade4","repo":"hashicorp/terraform","slug":"interrupted-last-error-v","errorCode":null,"errorMessage":"interrupted - last error: %v","messagePattern":"interrupted - last error: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/communicator/communicator.go","lineNumber":164,"sourceCode":"\t\t}\n\t}()\n\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":146,"sourceCodeEnd":174,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/communicator/communicator.go#L146-L174","documentation":"Surfaced by the communicator Retry loop when the operation context was cancelled (context.Canceled) before the connection/command succeeded. The %v is the last retryable error encountered before interruption. It distinguishes a user/manual interrupt from a timeout (separate message). This is the SSH/provisioner retry wrapper, not the Terraform run context.","triggerScenarios":"The user pressed Ctrl-C during a remote-exec provisioner run or file upload, cancelling the connection block's context. Also when a parent context is cancelled programmatically while Retry() is backing off between attempts.","commonSituations":"Interrupting a long-running provisioner that was stuck retrying SSH connections to a not-yet-ready host; CI pipeline cancellation while provisioners execute; a wrapper tool cancelling the apply context.","solutions":["If intentional, no fix needed — the interrupt was honoured.","If accidental, re-run terraform apply; the resource state is preserved and the provisioner will retry on the next apply if configured with on_failure = continue or via taint.","Address the underlying last error shown in %v so the host becomes reachable faster next time (e.g. security group, user_data timing)."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// If you wrap terraform in Go, distinguish cancel from other errors:\nerr := runApply(ctx, opts)\nif err != nil && strings.Contains(err.Error(), \"interrupted - last error\") {\n    // user-initiated cancel; surface cleanly, optionally offer resume\n    return status.Error(codes.Canceled, err.Error())\n}","preventionTips":["When cancelling, do so once and let the retry loop unwind cleanly.","Investigate the 'last error' in the message to prevent the same stall next run.","Use on_failure = continue on non-critical provisioners so a stall doesn't abort the whole apply."],"tags":["terraform","connection","retry","context-cancel","provisioner"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}