Recover a transfer
Choose the right recovery action
| Observed state | Action | Authority and cost |
|---|---|---|
| No successful source receipt | Check wallet/RPC/source revert first | Do not assume a cross-chain message exists |
| Source confirmed, destination pending | Check confirmations, transport and indexing | No duplicate source send |
| Router failedMessages(guid) is nonzero | Retry the exact message or restore a failed transfer | Retry is permissionless; destination gas applies |
| Endpoint failure, no router failure record | Endpoint-level delivery retry | Use the exact verified packet and appropriate execution gas |
| Execution reverted with InsufficientReceiveGas | Re-execute at the Endpoint with more gas | Permissionless; the packet stays pending, nothing is lost |
| Source confirmed, never verified on the destination | Wait; if the route is down, see Route outages | Not a message failure: the route's DVNs are not verifying |
| Transfer delivered, compose failed | Retry the queued compose or use application refunds | Router restore does not reverse a delivered credit |
| Original message is restored | Follow its restoreGuid | New message must deliver before the refund is settled |
Read failedMessages(guid) on the destination router. It stores a message hash, source EID, nonce and failure time—not the payload.
Recover the payload
Read PacketSent from the source transaction's LayerZero Endpoint. Match the GUID and extract the exact Omnisea message bytes. Verify its hash against the recorded failure. Do not rebuild it from displayed amounts or metadata.
Validate the log emitter against the source router's Endpoint, PacketV1 version, source/destination EIDs, router sender/receiver and GUID. The packet header is 81 bytes, followed by the 32-byte GUID, then the protocol message. Reject a mismatched hash even if the UI says the transfer failed. Archive source receipts or packet bytes so recovery does not depend on a provider retaining logs indefinitely.
Download the checked packet decoder. It accepts the exact source receipt and route identifiers, and checks the failure hash before returning message bytes. It does not send a recovery transaction.
Retry
Call retry(guid, message) on the destination router. Anyone may retry a recorded transfer, sync or owner message after fixing the cause. Simulation can expose an unresolved problem.
Restore
Only a failed transfer supports restore(guid, message, extraOptions). Quote with the destination Lens quoteRestore and pay that fee on the destination chain.
During the first seven days the original message's restorer may restore (sender by default). A sender can nominate a destination restorer using 32-byte oftCmd on the original send. After seven days anyone can request restoration. The destination of the refund remains the original sender regardless of who requests it.
Follow MessageRestored.restoreGuid until its return message is delivered. Only the net amount returns; source fees are retained.
Failures still held at the LayerZero Endpoint, including a failed restore execution, require Endpoint-level retry tools rather than another router restore.
Route outages
A route needs three of its five DVNs to verify messages. If fewer respond, that route stops delivering. Other routes keep working, and Omnisea can restore the route itself.
Detect it. Messages on one route stay pending well past normal delivery while other routes deliver. Poll /monitoring/stuck-messages?chainId=…&minAgeMinutes=… and alert per route.
Stop sending on it. The contracts cannot pause a route, and a send on it can still succeed on the source. Stop offering that route in your UI until it recovers.
Route around it. Move funds in two transfers through a chain whose routes to both sides work. For a dead A ↔ B route with A as the origin:
- Pick a detour chain C that the asset uses and that has healthy routes to A and B. If none exists, Omnisea adds one.
- The issuer enables C where it is not enabled yet:
enableChainon the origin A, and directly on B (no message needed, so the dead route does not matter). - Holders send B → C, then C → A to redeem the original token.
Wait for the rescue. Omnisea can lower the route's threshold so that the DVNs still running are enough, down to one of the five (RouteThresholdSet is emitted on the receiving chain). Messages already sent then verify and deliver as usual, and the route carries new transfers again. No action is needed from senders or issuers; keep the GUIDs of pending messages to confirm delivery.
The detour is for holders who need to move before that, or if none of the five DVNs is left on the route.