hashicorp/terraform · error
Failed to make %s HTTP request: %s
Error message
Failed to make %s HTTP request: %s
What it means
Inside httpClient.httpRequest, retryablehttp.NewRequest() returned an error before any network call. retryablehttp wraps net/http.NewRequest, so this indicates malformed method, an invalid URL string, or an unreadable body reader — a request-construction problem, not a transport one. The '%s' is the human label of the operation (get state / upload state / lock / unlock / delete state).
Source
Thrown at internal/backend/remote-state/http/client.go:53
Client *retryablehttp.Client
Username string
Password string
lockID string
jsonLockInfo []byte
}
func (c *httpClient) httpRequest(method string, url *url.URL, data *[]byte, what string) (*http.Response, error) {
// If we have data we need a reader
var reader io.Reader = nil
if data != nil {
reader = bytes.NewReader(*data)
}
// Create the request
req, err := retryablehttp.NewRequest(method, url.String(), reader)
if err != nil {
return nil, fmt.Errorf("Failed to make %s HTTP request: %s", what, err)
}
// Set up basic auth
if c.Username != "" {
req.SetBasicAuth(c.Username, c.Password)
}
// Work with data/body
if data != nil {
req.Header.Set("Content-Type", "application/json")
req.ContentLength = int64(len(*data))
// Generate the MD5
hash := md5.Sum(*data)
b64 := base64.StdEncoding.EncodeToString(hash[:])
req.Header.Set("Content-MD5", b64)
}
// Make the requestView on GitHub (pinned to c9def3e214)
Solutions
- Validate lock_method, unlock_method, and update_method are uppercase valid HTTP method tokens (GET/POST/PUT/LOCK/UNLOCK/etc.).
- Confirm the address/lock_address/unlock_address values do not contain stray control characters or whitespace after URL encoding.
- If reproducing in a wrapper, construct the same retryablehttp.NewRequest in a unit test to surface the precise error.
Example fix
// before update_method = "PUT " // after update_method = "PUT"
Defensive patterns
Strategy: validation
Validate before calling
import (
"github.com/hashicorp/go-retryablehttp"
)
func validateHTTPRequest(method string, u string) error {
_, err := retryablehttp.NewRequest(method, u, nil)
return err
} Type guard
func isValidMethod(m string) bool {
if m == "" { return false }
for _, r := range m {
if r < 'A' || r > 'Z' { return false }
}
return true
} Prevention
- Use only uppercase RFC 7230 method tokens for *_method attributes.
- URL-encode dynamic address components.
- Smoke-test method/URL construction in a unit test mirroring httpRequest.
When it happens
Trigger: A URL whose .String() produces something http.NewRequest rejects (control characters in host/path), an empty or non-token HTTP method in lock_method/unlock_method/update_method, or a nil body reader passed where one is required. Fires on the first state operation (Get/Put/Delete/Lock/Unlock) after Configure.
Common situations: Custom update_method set to an invalid token like "POST " with trailing space; lock_method misconfigured to lowercase "lock"; URL constructed with embedded NUL bytes from a bad template substitution.
Related errors
- HTTP remote state endpoint requires auth
- HTTP remote state already locked, failed to read body
- HTTP remote state already locked, failed to unmarshal body
- Unexpected HTTP response code %d
- HTTP remote state internal server error
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/79fa4edce71ec0d3.
Report an issue: GitHub.