hashicorp/terraform · warning

Ephemeral resources failed to Close during renew operations

Error message

Ephemeral resources failed to Close during renew operations

What it means

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.

Solutions

  1. Identify which ephemeral resource did not close by correlating with surrounding log lines (the diag itself carries no per-resource context).
  2. Update the provider; a well-behaved provider must honour context cancellation in Close/Renew.
  3. File a provider bug if Close does not return promptly after context cancellation.
  4. If unavoidable, reduce the number of long-lived ephemeral resources or shorten their renewal windows so Close drains faster.

Example fix

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.
Defensive patterns

Strategy: try-catch

Validate before calling

n/a — internal Close timeout; not preventable by caller input validation.

Type guard

func isEphemeralCloseTimeout(err error) bool {
    return err != nil && strings.Contains(err.Error(), "failed to Close during renew")
}

Try / catch

diags := resources.Close(ctx)
for _, d := range diags {
    if strings.Contains(d.Description().Summary, "failed to Close during renew") {
        // log provider misbehavior; correlate via surrounding log lines
        log.Printf("[WARN] ephemeral provider did not close within 10s")
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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

Appendix: source

Thrown at internal/resources/ephemeral/ephemeral_resources.go:193

	// All renew loops should have returned, or else we're going to leak
	// resources which could be continually renewing, or even interfering with
	// the same resources during the next operation.
	//
	// Use an asynchronous check so we can timeout and report the problem.
	done := make(chan int)
	go func() {
		r.wg.Wait()
		close(done)
	}()
	select {
	case <-done:
		// OK!
	case <-time.After(10 * time.Second):
		// This is probably harmless a lot of time, but is also indicative of an
		// ephemeral resource which would be misbehaving. The message isn't
		// very helpful with no context, so we'll have to rely on correlating
		// the problem via other log messages.
		diags = diags.Append(errors.New("Ephemeral resources failed to Close during renew operations"))
	}

	return diags
}

type resourceInstanceInternal struct {
	value      cty.Value
	configBody hcl.Body
	impl       ResourceInstance

	renewCancel func()
	renewDiags  tfdiags.Diagnostics
	renewMu     sync.Mutex // hold when accessing renewCancel/renewDiags, and while actually renewing
}

// close halts this instance's asynchronous renewal loop, if any, and then
// calls Close on the resource instance's implementation object.
//

View on GitHub (pinned to d32a084675)