How Cross-Chain Retries Recover Failed Calls
A failed destination call does not have to strand a transfer: retries can restore the action, but only when the bridge separates delivery from execution.
The Token Wire Desk3 min read
Cross-chain retries let a destination action run again after its first attempt fails, without sending the original transfer again. That matters because a message can reach another chain even when the contract call it asks for cannot finish. Treating delivery and execution as separate steps gives the system a way to recover.
A relay bridge can deliver a message that asks a destination contract to release tokens or update a record. The destination call may fail because it runs out of gas, hits a temporary condition, or cannot meet a contract check. For details on the gas problem, see how a relay bridge handles short destination gas. A retry design needs to preserve the message so the action can be attempted again.
What happens when a destination call fails?
The bridge should record delivery separately from whether the requested action succeeded. If the destination transaction reverts, its changes are undone, but the source-chain transfer may already be final. The message therefore needs a status that says it was received but still needs execution. Without that distinction, users and operators may not know whether to retry or whether funds have moved.
Some systems let a user or relayer submit the same message again. A relayer is a service that carries messages between chains. The retry should use the original message and its proof, rather than create a new transfer. This keeps recovery tied to the action that failed.
How can a retry avoid running the action twice?
A safe retry checks whether that specific message has already completed. Contracts commonly track a unique message ID and mark it complete only after the destination action succeeds. If the first attempt reverts, the completion mark also reverts, leaving the message eligible for another attempt.
This is called idempotency: repeating an operation has no extra effect after it succeeds. It matters when a transaction succeeds but the caller does not receive a clear response. Without a completion check, a second attempt could release funds or perform another action twice.
- Give every message a stable, unique ID.
- Mark it complete only when the requested action succeeds.
- Make failed attempts leave the message available for retry.
- Show users whether a message is delivered, pending, or complete.
Who should pay for another attempt?
Every destination call uses gas, the fee paid to run a transaction on that chain. A retry needs someone to pay that fee. The protocol may cover it, the user may submit the retry, or a relayer may do it for a fee. Each choice shifts cost and control: user-paid retries are direct but require the user to act, while relayer-paid retries can reduce effort but need a clear payment rule.
Retrying cannot make a permanently invalid action succeed. If a contract check will always fail, more gas only repeats the failure. A useful design explains the failure reason where possible and gives the user a clear next step. Watch how bridges report pending messages, who can retry them, and whether the completion record prevents duplicate execution.