{"record":{"id":"4bf6de2f0c71f4cc","repo":"hashicorp/terraform","slug":"ephemeral-resources-failed-to-close-during-renew-o","errorCode":null,"errorMessage":"Ephemeral resources failed to Close during renew operations","messagePattern":"Ephemeral resources failed to Close during renew operations","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/resources/ephemeral/ephemeral_resources.go","lineNumber":193,"sourceCode":"\t// All renew loops should have returned, or else we're going to leak\n\t// resources which could be continually renewing, or even interfering with\n\t// the same resources during the next operation.\n\t//\n\t// Use an asynchronous check so we can timeout and report the problem.\n\tdone := make(chan int)\n\tgo func() {\n\t\tr.wg.Wait()\n\t\tclose(done)\n\t}()\n\tselect {\n\tcase <-done:\n\t\t// OK!\n\tcase <-time.After(10 * time.Second):\n\t\t// This is probably harmless a lot of time, but is also indicative of an\n\t\t// ephemeral resource which would be misbehaving. The message isn't\n\t\t// very helpful with no context, so we'll have to rely on correlating\n\t\t// the problem via other log messages.\n\t\tdiags = diags.Append(errors.New(\"Ephemeral resources failed to Close during renew operations\"))\n\t}\n\n\treturn diags\n}\n\ntype resourceInstanceInternal struct {\n\tvalue      cty.Value\n\tconfigBody hcl.Body\n\timpl       ResourceInstance\n\n\trenewCancel func()\n\trenewDiags  tfdiags.Diagnostics\n\trenewMu     sync.Mutex // hold when accessing renewCancel/renewDiags, and while actually renewing\n}\n\n// close halts this instance's asynchronous renewal loop, if any, and then\n// calls Close on the resource instance's implementation object.\n//","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/resources/ephemeral/ephemeral_resources.go#L175-L211","documentation":"Appended to Close's diagnostics when an internal 10-second timeout elapses waiting for all ephemeral-resource renewal goroutines to drain (r.wg.Wait). It indicates an ephemeral resource provider whose Close (or a blocking renew call) did not return within the deadline, so Terraform is giving up waiting and reporting potential resource leakage. The comment notes it is often harmless but signals a misbehaving provider.","triggerScenarios":"Resources.Close spawns a goroutine that waits on r.wg; the select at ephemeral_resources.go:185-194 fires the time.After(10*time.Second) branch before the wait-group reaches zero. Happens when a provider's Renew or Close on an ephemeral resource blocks indefinitely or very slowly.","commonSituations":"A provider bug where the Close/Renew RPC handler deadlocks or ignores context cancellation; an ephemeral resource backed by a remote system under heavy load; provider still performing I/O after Terraform asked it to close.","solutions":["Identify which ephemeral resource did not close by correlating with surrounding log lines (the diag itself carries no per-resource context).","Update the provider; a well-behaved provider must honour context cancellation in Close/Renew.","File a provider bug if Close does not return promptly after context cancellation.","If unavoidable, reduce the number of long-lived ephemeral resources or shorten their renewal windows so Close drains faster."],"exampleFix":"n/a — indicates a provider-side defect; no caller-side code change fixes the underlying provider. Mitigate by updating the provider and correlating via logs.","handlingStrategy":"try-catch","validationCode":"n/a — internal Close timeout; not preventable by caller input validation.","typeGuard":"func isEphemeralCloseTimeout(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"failed to Close during renew\")\n}","tryCatchPattern":"diags := resources.Close(ctx)\nfor _, d := range diags {\n    if strings.Contains(d.Description().Summary, \"failed to Close during renew\") {\n        // log provider misbehavior; correlate via surrounding log lines\n        log.Printf(\"[WARN] ephemeral provider did not close within 10s\")\n    }\n}","preventionTips":["Use providers whose Close/Renew honour context cancellation.","Keep providers up to date; report deadlock bugs upstream.","Correlate the diagnostic with provider log lines to identify the offending resource."],"tags":["ephemeral-resources","goroutine-leak","timeout","terraform"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}