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 request

View on GitHub (pinned to c9def3e214)

Solutions

  1. Validate lock_method, unlock_method, and update_method are uppercase valid HTTP method tokens (GET/POST/PUT/LOCK/UNLOCK/etc.).
  2. Confirm the address/lock_address/unlock_address values do not contain stray control characters or whitespace after URL encoding.
  3. 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

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


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/79fa4edce71ec0d3. Report an issue: GitHub.