micro/go-micro · error

failed to read response: %w

Error message

failed to read response: %w

What it means

Returned by Provider.callAPI when reading the response body with io.ReadAll fails after the HTTP request completed. This is rare and indicates the connection was reset or dropped mid-body read — the response headers arrived but the body could not be fully consumed.

Source

Thrown at ai/anthropic/anthropic.go:381

		return nil, nil, fmt.Errorf("failed to create request: %w", err)
	}

	// Set headers
	httpReq.Header.Set("Content-Type", "application/json")
	httpReq.Header.Set("x-api-key", p.opts.APIKey)
	httpReq.Header.Set("anthropic-version", "2023-06-01")

	// Make request
	httpResp, err := http.DefaultClient.Do(httpReq)
	if err != nil {
		return nil, nil, fmt.Errorf("API request failed: %w", err)
	}
	defer httpResp.Body.Close()

	// Read response
	respBody, err := io.ReadAll(httpResp.Body)
	if err != nil {
		return nil, nil, fmt.Errorf("failed to read response: %w", err)
	}
	if httpResp.StatusCode != http.StatusOK {
		return nil, nil, ai.NewHTTPError(httpResp, respBody)
	}

	// Parse response
	var anthropicResp struct {
		Content []struct {
			Type  string          `json:"type"`
			Text  string          `json:"text"`
			ID    string          `json:"id"`
			Name  string          `json:"name"`
			Input json.RawMessage `json:"input"`
		} `json:"content"`
		StopReason string `json:"stop_reason"`
	}

	if err := json.Unmarshal(respBody, &anthropicResp); err != nil {

View on GitHub (pinned to 24529f1404)

Solutions

  1. Retry the request — transient body-read resets usually succeed on a second attempt with fresh connection.
  2. Set a custom http.Client with sensible Timeout and DisableKeepAlives or Transport settings to avoid stale reused connections.
  3. Rule out intermediary proxies/VPNs by testing on the same host with curl.
  4. Increase load balancer/proxy idle timeouts if the failures correlate with slow responses.

Example fix

// before
resp, err := provider.Generate(ctx, prompt)
if err != nil { return err }
// after
resp, err := provider.Generate(ctx, prompt)
if err != nil && isTransientNetErr(err) { resp, err = provider.Generate(ctx, prompt) } // one retry
Defensive patterns

Strategy: retry

Try / catch

var resp *ai.Response
var err error
for i := 0; i < 2; i++ { // one retry for transient body-read resets
	resp, err = provider.Generate(ctx, prompt)
	if err == nil || !errors.Is(err, io.ErrUnexpectedEOF) && !strings.Contains(err.Error(), "failed to read response") { break }
	time.Sleep(250*time.Millisecond)
}

Prevention

When it happens

Trigger: io.ReadAll(httpResp.Body) errors: connection reset by peer mid-response, network interruption while transferring the body, proxy terminating the connection early, or an abruptly closed keep-alive connection.

Common situations: Flaky networks or NAT timeouts dropping long-lived connections, load balancers with short idle timeouts, VPN instability, or proxies closing connections on slow Anthropic responses.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/441d04fa9207ff48. Report an issue: GitHub.