hashicorp/terraform · error
invalid retry_max: %s
Error message
invalid retry_max: %s
What it means
Configure calls backendbase.IntValue on the retry_max attribute (default 2, env TF_HTTP_RETRY_MAX). If the supplied cty.Number cannot be converted to an int — e.g. it is a fractional float, out-of-range, or not a number at all — IntValue returns an error which is wrapped here. retry_max controls how many times go-retryablehttp retries a failed request.
Source
Thrown at internal/backend/remote-state/http/backend.go:195
return backendbase.ErrorAsDiagnostics(
fmt.Errorf("unlock_address must be HTTP or HTTPS"),
)
}
}
unlockMethod := backendbase.GetAttrEnvDefaultFallback(
configVal, "unlock_method",
"TF_HTTP_UNLOCK_METHOD", cty.StringVal("UNLOCK"),
).AsString()
retryMax, err := backendbase.IntValue(
backendbase.GetAttrEnvDefaultFallback(
configVal, "retry_max",
"TF_HTTP_RETRY_MAX", cty.NumberIntVal(2),
),
)
if err != nil {
return backendbase.ErrorAsDiagnostics(
fmt.Errorf("invalid retry_max: %s", err),
)
}
retryWaitMin, err := backendbase.IntValue(
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),
),View on GitHub (pinned to c9def3e214)
Solutions
- Set retry_max to a whole, non-negative integer (e.g. retry_max = 2).
- Remove the line to accept the default of 2.
- If set via TF_HTTP_RETRY_MAX, ensure the env value is a plain integer string with no decimal point.
Example fix
// before retry_max = 2.5 // after retry_max = 2
Defensive patterns
Strategy: validation
Validate before calling
// Ensure retry_max is an integer before terraform init
func validateRetryMax(v interface{}) error {
n, ok := v.(int)
if !ok { return fmt.Errorf("retry_max must be int, got %T", v) }
if n < 0 { return fmt.Errorf("retry_max must be >= 0") }
return nil
} Type guard
func isRetryInt(v cty.Value) bool {
return v.Type() == cty.Number && !v.IsNull() && v.AsBigFloat().IsInt()
} Prevention
- Use whole integers for all retry_* settings.
- Document the unit (requests vs seconds) next to each retry_* attribute.
- Reject fractional defaults in shared module inputs.
When it happens
Trigger: Setting retry_max to a non-integer number like 2.5, a huge value overflowing int, or feeding a value that HCL evaluates as a non-number. Triggered at backend Configure time.
Common situations: Operator writes retry_max = 2.5 thinking fractional retries are allowed; passes a string "3" expecting coercion; CI template injects a float from a YAML config.
Related errors
- invalid retry_wait_min: %s
- invalid retry_wait_max: %s
- failed to parse unlock_address URL: %s
- unlock_address must be HTTP or HTTPS
- client_certificate_pem is set but client_private_key_pem is
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/489f75a320d8edc3.
Report an issue: GitHub.