hashicorp/terraform · error
HTTP error: %d
Error message
HTTP error: %d
What it means
The HTTP backend's Put() (state upload) received a status code other than 200, 201, or 204. These are the only success codes accepted for a POST/PUT state write; anything else (including redirects or 4xx/5xx) is reported as a generic HTTP error with the numeric code.
Source
Thrown at internal/backend/remote-state/http/client.go:241
}
*/
var method string = "POST"
if c.UpdateMethod != "" {
method = c.UpdateMethod
}
resp, err := c.httpRequest(method, &base, &data, "upload state")
if err != nil {
return diags.Append(err)
}
defer resp.Body.Close()
// Handle the error codes
switch resp.StatusCode {
case http.StatusOK, http.StatusCreated, http.StatusNoContent:
return diags
default:
return diags.Append(fmt.Errorf("HTTP error: %d", resp.StatusCode))
}
}
func (c *httpClient) Delete() tfdiags.Diagnostics {
var diags tfdiags.Diagnostics
// Make the request
resp, err := c.httpRequest("DELETE", c.URL, nil, "delete state")
if err != nil {
return diags.Append(err)
}
defer resp.Body.Close()
// Handle the error codes
switch resp.StatusCode {
case http.StatusOK:
return diags
default:View on GitHub (pinned to c9def3e214)
Solutions
- Use TF_LOG=DEBUG to capture the exact status code, then address the server-side cause for that code.
- If 405, set the correct `update_method` ("POST" or "PUT") matching what the state endpoint accepts.
- If 401/403, refresh or correct the username/password (or token) credentials for the state endpoint.
- If 413, raise the server's max body size limit to accommodate the state payload.
- If 409, the state is locked elsewhere; run `terraform force-unlock` or wait for the other run to finish.
Example fix
# before - server only accepts PUT but default POST is used
backend "http" {
address = "https://state.example.com/tf"
}
# after - specify the method the endpoint accepts
backend "http" {
address = "https://state.example.com/tf"
update_method = "PUT"
} Defensive patterns
Strategy: validation
Validate before calling
# Probe the write endpoint with the method Terraform will use before running apply
curl -sS -o /dev/null -w "%{http_code}" -X "$METHOD" \
-H "Content-Type: application/json" \
-u "$USER:$PASS" --data-binary @small.json "$STATE_URL"
# expect 200, 201, or 204 Prevention
- Set update_method to match what the endpoint accepts (POST vs PUT).
- Ensure the configured credentials have write permission and have not expired.
- Confirm the server's max body size exceeds your state size to avoid 413.
When it happens
Trigger: Calling Put() during `terraform apply`/`terraform destroy` to persist state, where the server responds with a non-success code such as 401, 403, 405 (method not allowed), 409 (conflict/lock), 413 (payload too large), or 500.
Common situations: The state endpoint does not allow POST/PUT (returns 405) when UpdateMethod is misconfigured; the server rejects large state bodies (413); authentication expired between read and write (401/403); a concurrent lock returns 409; a server error during write (500).
Related errors
- Failed to read remote state: %s
- resp.Status
- resp.Status
- failed to save file to %v: %v
- Failed to upload state to %v: %v
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/d29c5a5fea23e4eb.
Report an issue: GitHub.