hashicorp/terraform · error

invalid retry_wait_max: %s

Error message

invalid retry_wait_max: %s

What it means

IntValue conversion failure for retry_wait_max (default 30 seconds, env TF_HTTP_RETRY_WAIT_MAX), the upper bound on retryablehttp backoff. Identical mechanism to errors 242/243: a non-integer, out-of-range, or uncoercible cty.Number triggers it. Note Configure does not validate retry_wait_max >= retry_wait_min.

Source

Thrown at internal/backend/remote-state/http/backend.go:217

		backendbase.GetAttrEnvDefaultFallback(
			configVal, "retry_wait_min",
			"TF_HTTP_RETRY_WAIT_MIN", cty.NumberIntVal(1),
		),
	)
	if err != nil {
		return backendbase.ErrorAsDiagnostics(
			fmt.Errorf("invalid retry_wait_min: %s", err),
		)
	}
	retryWaitMax, err := backendbase.IntValue(
		backendbase.GetAttrEnvDefaultFallback(
			configVal, "retry_wait_max",
			"TF_HTTP_RETRY_WAIT_MAX", cty.NumberIntVal(30),
		),
	)
	if err != nil {
		return backendbase.ErrorAsDiagnostics(
			fmt.Errorf("invalid retry_wait_max: %s", err),
		)
	}

	rClient := retryablehttp.NewClient()
	rClient.RetryMax = int(retryMax)
	rClient.RetryWaitMin = time.Duration(retryWaitMin) * time.Second
	rClient.RetryWaitMax = time.Duration(retryWaitMax) * time.Second
	rClient.Logger = log.New(logging.LogOutput(), "", log.Flags())
	if err = b.configureTLS(rClient, configVal); err != nil {
		return backendbase.ErrorAsDiagnostics(err)
	}

	b.client = &httpClient{
		URL:          updateURL,
		UpdateMethod: updateMethod,

		LockURL:      lockURL,
		LockMethod:   lockMethod,

View on GitHub (pinned to c9def3e214)

Solutions

  1. Set retry_wait_max to a positive integer >= retry_wait_min (e.g. retry_wait_max = 30).
  2. Verify TF_HTTP_RETRY_WAIT_MAX is a bare integer string.
  3. Remove the attribute to fall back to the default of 30 seconds.

Example fix

// before
retry_wait_max = 30.5
retry_wait_min   = 40
// after
retry_wait_max = 30
retry_wait_min = 1
Defensive patterns

Strategy: validation

Validate before calling

func validateRetryWaits(minV, maxV interface{}) error {
  if err := validateRetryWait(minV, "retry_wait_min"); err != nil { return err }
  if err := validateRetryWait(maxV, "retry_wait_max"); err != nil { return err }
  if minV.(int) > maxV.(int) {
    return fmt.Errorf("retry_wait_min (%d) > retry_wait_max (%d)", minV, maxV)
  }
  return nil
}

Prevention

When it happens

Trigger: Setting retry_wait_max to a fractional or out-of-range value, or inverting it below retry_wait_min (which Configure permits but yields odd backoff behavior). Fires at Configure time.

Common situations: Operator enters 30.0 expecting int coercion; copies a float from monitoring dashboards; sets retry_wait_max lower than retry_wait_min by mistake.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/7158fdf1e431705f. Report an issue: GitHub.