Skip to content

feat(adk): retry A2A requests on transport error - #2827

Open
anthonyhaussman wants to merge 1 commit into
kagent-dev:mainfrom
anthonyhaussman:tone/fix/a2a-retry-transport
Open

anthonyhaussman wants to merge 1 commit into
kagent-dev:mainfrom
anthonyhaussman:tone/fix/a2a-retry-transport

Conversation

@anthonyhaussman

@anthonyhaussman anthonyhaussman commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Problem

Same-cluster agent-to-agent (A2A) calls (pod-to-pod on port 8080) go directly through remoteA2ATool's HTTP client and never pass through any gateway/proxy layer.
When the target agent pod is evicted or replaced mid-request (e.g. node consolidation, rolling update), the in-flight connection is torn down and SendMessage fails with a raw transport error such as:

failed to send HTTP request: Post "http://<agent>.<ns>:8080": EOF

remoteA2AState's handleFirstCall / handleResume each call client.SendMessage exactly once.
There is no retry anywhere in the A2A client stack (remote_a2a_tool.go, a2aclient, or the underlying a2a-go transport), so any pod churn during a call surfaces directly to the end user as a hard failure, even though a retry a few hundred milliseconds later would very likely succeed once the Service's endpoint list catches up.

Fix

Add a small http.RoundTripper (retry_transport.go) that wraps the A2A tool's http.Client and retries only on transport-level failures:
io.EOF, io.ErrUnexpectedEOF, and *net.OpError (dial/read/write failures).

It never retries based on a received response status code, and it never retries when the request body cannot be safely replayed (req.GetBody == nil).

Retry policy: up to 3 attempts total, with a 250ms base delay that doubles between attempts, bounded by the request's context deadline.

The transport is wired in as the innermost layer, underneath the existing otelhttp transport, so a single logical A2A call (including any internal retries) still produces one trace span.

This covers both client.SendMessage call sites in remote_a2a_tool.go as well as agent-card resolution agentcard.NewResolver(...).Resolve), since both share the same wrapped http.Client.

Configuration

The retry is disabled by default and opt-in via env var, tunable through:

  • KAGENT_A2A_RETRY_ENABLED (bool, default false)
  • KAGENT_A2A_RETRY_MAX_ATTEMPTS (int, default 3)
  • KAGENT_A2A_RETRY_BASE_DELAY (duration, default 250ms)

@anthonyhaussman
anthonyhaussman marked this pull request as draft September 15, 2026 19:59
@github-actions github-actions Bot added the bug Something isn't working label Sep 15, 2026
@anthonyhaussman
anthonyhaussman force-pushed the tone/fix/a2a-retry-transport branch from 2b7a4d1 to a35d23e Compare September 15, 2026 20:06
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Sep 15, 2026
@anthonyhaussman anthonyhaussman changed the title fix(adk): retry A2A requests on transport error feat(adk): retry A2A requests on transport error Sep 15, 2026
@github-actions github-actions Bot added enhancement New feature or request and removed bug Something isn't working labels Sep 15, 2026
@anthonyhaussman
anthonyhaussman force-pushed the tone/fix/a2a-retry-transport branch from a35d23e to c7f9e11 Compare September 15, 2026 20:25
@anthonyhaussman
anthonyhaussman marked this pull request as ready for review September 15, 2026 20:27
Same-cluster A2A calls skip agentgateway entirely,
so pod eviction mid-request surfaces a raw EOF.
SendMessage made exactly one attempt with no retry.
Wrap the HTTP client with a transport-level retry,
three attempts with 250ms doubling backoff, matching
agentgateway's existing federation retry policy.
Only retries EOF and net.OpError, never response
codes, keeping status-code retry as agentgateway's job.
Disabled by default, tunable via KAGENT_A2A_RETRY_ENABLED,
KAGENT_A2A_RETRY_MAX_ATTEMPTS and KAGENT_A2A_RETRY_BASE_DELAY.

Assisted-by: Claude Sonnet 5
Signed-off-by: Anthony Hausman <[email protected]>
@anthonyhaussman
anthonyhaussman force-pushed the tone/fix/a2a-retry-transport branch from c7f9e11 to 2b3e54f Compare September 15, 2026 20:28
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Sep 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant