{"record":{"id":"489f75a320d8edc3","repo":"hashicorp/terraform","slug":"invalid-retry-max-s","errorCode":null,"errorMessage":"invalid retry_max: %s","messagePattern":"invalid retry_max: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/http/backend.go","lineNumber":195,"sourceCode":"\t\t\treturn backendbase.ErrorAsDiagnostics(\n\t\t\t\tfmt.Errorf(\"unlock_address must be HTTP or HTTPS\"),\n\t\t\t)\n\t\t}\n\t}\n\tunlockMethod := backendbase.GetAttrEnvDefaultFallback(\n\t\tconfigVal, \"unlock_method\",\n\t\t\"TF_HTTP_UNLOCK_METHOD\", cty.StringVal(\"UNLOCK\"),\n\t).AsString()\n\n\tretryMax, err := backendbase.IntValue(\n\t\tbackendbase.GetAttrEnvDefaultFallback(\n\t\t\tconfigVal, \"retry_max\",\n\t\t\t\"TF_HTTP_RETRY_MAX\", cty.NumberIntVal(2),\n\t\t),\n\t)\n\tif err != nil {\n\t\treturn backendbase.ErrorAsDiagnostics(\n\t\t\tfmt.Errorf(\"invalid retry_max: %s\", err),\n\t\t)\n\t}\n\tretryWaitMin, err := backendbase.IntValue(\n\t\tbackendbase.GetAttrEnvDefaultFallback(\n\t\t\tconfigVal, \"retry_wait_min\",\n\t\t\t\"TF_HTTP_RETRY_WAIT_MIN\", cty.NumberIntVal(1),\n\t\t),\n\t)\n\tif err != nil {\n\t\treturn backendbase.ErrorAsDiagnostics(\n\t\t\tfmt.Errorf(\"invalid retry_wait_min: %s\", err),\n\t\t)\n\t}\n\tretryWaitMax, err := backendbase.IntValue(\n\t\tbackendbase.GetAttrEnvDefaultFallback(\n\t\t\tconfigVal, \"retry_wait_max\",\n\t\t\t\"TF_HTTP_RETRY_WAIT_MAX\", cty.NumberIntVal(30),\n\t\t),","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/backend/remote-state/http/backend.go#L177-L213","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nretry_max = 2.5\n// after\nretry_max = 2","handlingStrategy":"validation","validationCode":"// Ensure retry_max is an integer before terraform init\nfunc validateRetryMax(v interface{}) error {\n  n, ok := v.(int)\n  if !ok { return fmt.Errorf(\"retry_max must be int, got %T\", v) }\n  if n < 0 { return fmt.Errorf(\"retry_max must be >= 0\") }\n  return nil\n}","typeGuard":"func isRetryInt(v cty.Value) bool {\n  return v.Type() == cty.Number && !v.IsNull() && v.AsBigFloat().IsInt()\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["config","type-coercion","http-backend","terraform"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}