hashicorp/terraform · error
Unexpected HTTP response code
Error message
Unexpected HTTP response code %d
What it means
The lock response status code was not one of 200/401/403/409/423. '%d' is the unexpected status. Common culprits: 404 (lock_address points to a non-existent route), 405 (the configured lock_method is not allowed by the server), 500/502/503 (server/gateway error), or 301/302 (redirect the client did not follow).
Solutions
- Confirm lock_address is correct: curl -i -X <lock_method> <lock_address>.
- If the server does not support the configured method, set lock_method to a verb it accepts (commonly POST or PUT).
- For 404, correct the lock_address path or remove it to disable locking.
- For 5xx, address the server-side error and retry.
- Ensure reverse proxies follow/forward the lock route and do not redirect to a different status.
Example fix
// before (server does not support LOCK verb -> 405) lock_method = "LOCK" // after lock_method = "POST"
Defensive patterns
Strategy: validation
Validate before calling
# Pre-flight: confirm the lock endpoint returns an expected status for the method
code=$(curl -sS -o /dev/null -w '%{http_code}' -u "$TF_HTTP_USERNAME:$TF_HTTP_PASSWORD" \
-X "${TF_HTTP_LOCK_METHOD:-LOCK}" "${TF_HTTP_LOCK_ADDRESS:-$TF_HTTP_ADDRESS}")
case "$code" in
200|201|204|401|403|409|423) echo "lock endpoint ok ($code)" ;;
*) echo "ERROR: unexpected lock status $code — check lock_address/lock_method"; exit 1 ;;
esac Prevention
- Confirm lock_address routes to a real lock endpoint (not the plain state URL).
- Match lock_method to a verb the server supports (POST/PUT are safest).
- Probe lock_address with curl -X <method> before terraform apply.
When it happens
Trigger: lock_address routes to a non-existent path (404); server does not implement the LOCK verb and returns 405 (typical when lock_method=LOCK against a generic web server); server error (500); reverse proxy misroutes the request.
Common situations: lock_address set equal to address but the server has no dedicated lock endpoint; lock_method=LOCK but the server only accepts POST/PUT; reverse proxy rewrites the path incorrectly; server's lock route moved.
Related errors
- Failed to make HTTP request
- failed to parse lock_address URL
- HTTP remote state endpoint invalid auth
- HTTP remote state endpoint requires auth
- lock_address must be HTTP or HTTPS
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/e36a70cd0709a4a2.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/http/client.go:122
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", &statemgr.LockError{
Err: fmt.Errorf("HTTP remote state already locked, failed to read body"),
}
}
existing := statemgr.LockInfo{}
err = json.Unmarshal(body, &existing)
if err != nil {
return "", &statemgr.LockError{
Err: fmt.Errorf("HTTP remote state already locked, failed to unmarshal body"),
}
}
return "", &statemgr.LockError{
Info: &existing,
Err: fmt.Errorf("HTTP remote state already locked: ID=%s", existing.ID),
}
default:
return "", fmt.Errorf("Unexpected HTTP response code %d", resp.StatusCode)
}
}
func (c *httpClient) Unlock(id string) error {
if c.UnlockURL == nil {
return nil
}
resp, err := c.httpRequest(c.UnlockMethod, c.UnlockURL, &c.jsonLockInfo, "unlock")
if err != nil {
return err
}
defer resp.Body.Close()
switch resp.StatusCode {
case http.StatusOK:
return nil
default:View on GitHub (pinned to d32a084675)