hashicorp/terraform · error

Failed to read remote state: %s

Error message

Failed to read remote state: %s

What it means

After the HTTP backend received an acceptable status code (200) for a Get(), reading the response body via io.Copy failed. This is a transport-level failure mid-stream rather than an HTTP protocol error; the underlying connection dropped or was reset while the body was being copied into a buffer.

Source

Thrown at internal/backend/remote-state/http/client.go:174

		// Handled after
	case http.StatusNoContent:
		return nil, diags
	case http.StatusNotFound:
		return nil, diags
	case http.StatusUnauthorized:
		return nil, diags.Append(fmt.Errorf("HTTP remote state endpoint requires auth"))
	case http.StatusForbidden:
		return nil, diags.Append(fmt.Errorf("HTTP remote state endpoint invalid auth"))
	case http.StatusInternalServerError:
		return nil, diags.Append(fmt.Errorf("HTTP remote state internal server error"))
	default:
		return nil, diags.Append(fmt.Errorf("Unexpected HTTP response code %d", resp.StatusCode))
	}

	// Read in the body
	buf := bytes.NewBuffer(nil)
	if _, err := io.Copy(buf, resp.Body); err != nil {
		return nil, diags.Append(fmt.Errorf("Failed to read remote state: %s", err))
	}

	// Create the payload
	payload := &remote.Payload{
		Data: buf.Bytes(),
	}

	// If there was no data, then return nil
	if len(payload.Data) == 0 {
		return nil, diags
	}

	// Check for the MD5
	if raw := resp.Header.Get("Content-MD5"); raw != "" {
		md5, err := base64.StdEncoding.DecodeString(raw)
		if err != nil {
			return nil, diags.Append(fmt.Errorf(
				"Failed to decode Content-MD5 '%s': %s", raw, err))

View on GitHub (pinned to c9def3e214)

Solutions

  1. Retry the Terraform command; transient mid-stream resets usually succeed on the next attempt.
  2. If recurring on large state, raise the read/idle timeouts on the reverse proxy in front of the state server.
  3. Verify network stability to the state endpoint (large download test via curl).
  4. Inspect TF_LOG=DEBUG output for the exact io error (e.g. 'connection reset by peer', 'unexpected EOF').
Defensive patterns

Strategy: retry

Try / catch

// Wrap remote-state reads and retry on transient io errors
for i := 0; i < 3; i++ {
    payload, diags := client.Get()
    if !diags.HasErrors() {
        return payload, nil
    }
    // transient read errors (connection reset, EOF) are retryable
    time.Sleep(backoff(i))
}
return nil, lastDiags

Prevention

When it happens

Trigger: A GET to the state URL returns 200 but the connection is closed or reset before the full body is delivered, causing io.Copy(resp.Body) to return a non-nil error at client.go:173.

Common situations: An intermediary proxy/load balancer with a short read timeout cutting the connection on large state files; flaky network or VPN dropping packets; the state server crashing mid-response; TLS renegotiation or keep-alive closure during a long download.

Related errors


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