gastownhall/beads · error
failed to read response (attempt %d/%d): %w
Error message
failed to read response (attempt %d/%d): %w
What it means
This error wraps an underlying I/O failure that occurred while reading the Jira HTTP response body in doRequest. The client reads up to MaxResponseSize bytes via io.ReadAll on a LimitReader; any read failure (connection reset mid-body, TLS error, premature EOF) is wrapped with the attempt counter (of MaxRetries+1) and the original error. The request is then retried until attempts are exhausted, after which the last wrapped error surfaces via 'max retries exceeded'.
Source
Thrown at internal/jira/client.go:381
}
c.setAuth(req)
req.Header.Set("Accept", "application/json")
req.Header.Set("User-Agent", "bd-jira-sync/1.0")
if body != nil {
req.Header.Set("Content-Type", "application/json")
}
resp, err := c.HTTPClient.Do(req)
if err != nil {
lastErr = fmt.Errorf("request failed (attempt %d/%d): %w", attempt+1, MaxRetries+1, err)
continue
}
respBody, err := io.ReadAll(io.LimitReader(resp.Body, MaxResponseSize))
_ = resp.Body.Close()
if err != nil {
lastErr = fmt.Errorf("failed to read response (attempt %d/%d): %w", attempt+1, MaxRetries+1, err)
continue
}
// PUT returns 204 No Content on success
if resp.StatusCode == http.StatusNoContent {
return nil, nil
}
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
return respBody, nil
}
// Permanent failures — no retry.
switch resp.StatusCode {
case http.StatusBadRequest, http.StatusUnauthorized, http.StatusForbidden, http.StatusNotFound:
return nil, fmt.Errorf("jira API returned %d: %s", resp.StatusCode, string(respBody))
}
View on GitHub (pinned to 71377f2769)
Solutions
- Retry the operation — the client already retries internally; if it fails all attempts, check network stability between client and the Jira host.
- Inspect the wrapped cause (%w) at the end of the message to identify the transport-level problem (e.g. 'connection reset by peer', 'unexpected EOF').
- Check for proxies/firewalls/load balancers between the client and Jira that terminate connections; raise their idle timeouts.
- If self-hosted Jira, check server logs and reverse-proxy (nginx/ALB) timeout settings.
- Verify TLS certificates and that the Jira URL scheme (http/https) is correct.
Example fix
// before: seeing 'failed to read response (attempt 3/4): unexpected EOF' with no insight
resp, _ := client.doRequest(ctx, req)
// after: log the unwrapped cause to diagnose the transport failure
if err != nil {
var unwrapped error = errors.Unwrap(err)
log.Printf("jira read failed, cause: %v", unwrapped)
} Defensive patterns
Strategy: retry
Validate before calling
// Verify reachability before issuing real calls
req, _ := http.NewRequestWithContext(ctx, "GET", jiraURL+"/rest/api/3/myself", nil)
if _, err := http.DefaultClient.Do(req); err != nil {
return fmt.Errorf("jira host unreachable, check network/proxy: %w", err)
} Try / catch
if err != nil {
if strings.Contains(err.Error(), "failed to read response") || strings.Contains(err.Error(), "max retries") {
// transient transport issue: back off and retry later
time.Sleep(backoff)
return retry(op)
}
return err
} Prevention
- Run bulk workloads on stable network paths; avoid flaky VPNs for long syncs.
- Set proxy/LB idle timeouts longer than the largest expected Jira response.
- Honor the wrapped cause (%w) in logs to distinguish read failures from status failures.
- Keep MaxResponseSize-aware expectations; very large responses over slow links are more read-failure prone.
When it happens
Trigger: io.ReadAll(resp.Body) returns a non-nil err during any retry attempt of doRequest — e.g. the server closes the connection mid-body, a proxy drops the stream, or a TLS read fails.
Common situations: Corporate proxies or load balancers with short idle timeouts killing long responses; flaky VPN/network; Jira instance (especially self-hosted) restarting under load; response larger than expected causing client/server disagreement.
Related errors
- failed to read response (attempt %d/%d): %w
- request failed (attempt %d/%d): %w
- fetch issue %s: %w
- search issues: %w
- get issue %s: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/859cd57494f9cee3.
Report an issue: GitHub.