Layer zero message state guides recovery decisions

Layer zero message recovery starts by distinguishing normal progress from an incomplete destination execution. A source transaction can succeed while verification is still pending; a verified packet can wait for execution; and a destination call can revert while the verified payload remains available for another attempt. Those conditions lead to different actions. Wait while verification is still developing, retry a retained payload after a recoverable execution failure, correct receiver logic before another call, reconcile application state after delivery or stop the packet through an authorized Endpoint control. The decision should follow the packet's origin, receiver, nonce, GUID, stored payload status and destination events rather than the source transaction alone.

The short version: Layer zero message recovery contrasts normal delivery with incomplete execution, using observable state to choose whether to wait, retry, reconcile, or stop.

Sent, verified and delivered evidence

Three records establish where a packet stopped. The source send proves emission, while destination verification proves acceptance of the payload hash under the pathway's Decentralized Verifier Network (DVN) rules. For a normal lzReceive call, PacketDelivered and the transaction trace together prove that receiver logic completed without reverting; an authorized clear call can emit the same event without calling the receiver. Preserve the source endpoint ID, sender, receiver, nonce, GUID and payload bytes as one identity set. A status label without those fields can conflate a delayed packet with a different send, especially after someone submits another source transaction.

The state split that selects recovery

A verified payload is not yet a delivered application action.

Before verification, lzReceive does not have an executable payload in the destination channel. A retry aimed at receiver logic cannot repair missing verification. Compare the original packet identity with the configured receive path: the source endpoint ID, remote peer, receive library and DVN requirements must describe the same direction. If those inputs match and verifier confirmations are still accumulating, waiting preserves the original packet. If they do not match, repeated execution calls will not change the verifying conditions.

A packet becomes verified only after the configured DVN rules are satisfied and its payload hash is committed to the destination Endpoint channel. At that point, the source data does not need to be sent again merely because execution has not happened. The stored payload and matching nonce provide the handoff evidence for destination execution.

An LzReceiveAlert only supports a receiver-failure diagnosis when its packet fields match a failed destination call and the payload hash remains stored. The failed transaction rolls back the payload deletion, so the packet remains available for another call. Read the alert alongside the destination transaction trace: an exhausted gas allowance supports a resource adjustment, while a receiver revert supports a code, parameter or application-state correction.

PacketDelivered closes the Endpoint delivery branch after a successful lzReceive call, while an authorized clear call can emit the same event without executing receiver logic. A later source send would create a separate packet rather than continue the original one. Use the destination application's state and events to confirm the intended business effect. If that effect is absent after a successful lzReceive call, the remaining work belongs to application reconciliation rather than protocol retry.

The state split that selects recovery: A packet becomes verified only after the configured DVN rules are satisfied and its payload hash is committed to the destination Endpoint channel.; At that point, the source data does not need to be sent again merely because execution has not happened. The stored payload and matching nonce provide the handoff evidence for destination execution.

View image file

Retry conditions after a receive alert

Two broad failure classes require different changes before another destination call. Gas exhaustion concerns the resources supplied for execution. A logic revert concerns the receiver's code, message parameters or current application state. Increasing gas without identifying the class may reproduce the same alert and add another failed transaction.

Cause isolation before another call

Insufficient execution resources

Message execution options specify the gas and value requested for the destination call. The source chain cannot know the exact destination state when the packet is sent, and execution cost can vary with the receiver's path through its logic. A trace or simulation should show whether the call exhausts its allowance. The next attempt can then supply an allowance based on that observed execution rather than changing the message.

Receiver logic and state

A deterministic receiver revert survives a larger gas allowance. The error may come from malformed parameters, an unmet prerequisite, a paused operation or an invariant inside the OApp. Correct the condition that produced the revert before trying the retained packet. If the original payload itself is invalid and the receiver cannot be changed to accept it safely, an authorized removal path may be more appropriate than repeated execution.

Retrying the retained payload

A retry calls the destination Endpoint with the original origin tuple, receiver, GUID and message bytes. The Endpoint compares those inputs with the stored payload hash before calling the receiver, so altered message data cannot stand in for the verified packet. The retry transaction may adjust execution resources, but it does not create a new source nonce or repeat verification. A composed call uses its corresponding lzCompose retry path instead of lzReceive.

A gas-bound failure with a reversible retry

In this hypothetical case, the destination gas allowance is the only changing input, rising from 54,216 to 86,416 gas units. The receiver code, application state, origin, receiver, nonce, GUID and message bytes remain fixed. Neither figure is a protocol default or recommended setting.

A gas-bound failure with a reversible retry: In this hypothetical case, the destination gas allowance is the only changing input, rising from 54,216 to 86,416 gas units.; The receiver code, application state, origin, receiver, nonce, GUID and message bytes remain fixed. Neither figure is a protocol default or recommended setting.

View image file

The destination record shows a verified payload, followed by LzReceiveAlert, while the payload hash remains stored. Successful delivery would instead produce PacketDelivered and remove that hash. A reversible simulation of the same receiver call exhausts the initial allowance before it can show whether receiver logic would later revert. Increasing only the hypothetical gas allowance tests that observed boundary without changing packet identity.

In this worked case, the retry with the hypothetical 86,416-unit allowance completes, PacketDelivered appears and the stored payload is cleared. If the retry emitted another alert or exposed a receiver-logic revert, the gas-only diagnosis would be invalid. Further calls should stop until that newly observed condition changes, because another allowance increase would not demonstrate a different cause.


Delivery evidence and application reconciliation

A successful Endpoint execution deletes the stored payload hash, preventing that verified payload from being executed again through the same channel entry. Reconciliation then moves to the receiver's own success evidence, such as the state variable or event defined by the OApp. A completed lzReceive does not prove that a later composed action also completed; lzCompose has a separate execution and retry path. That distinction prevents a compose failure from being mistaken for a failed base delivery.


Irreversible controls and authority boundaries

Four Endpoint controls cover cases that ordinary waiting or retrying cannot resolve: skip, clear, nilify and burn. They act on different message states and are not substitutes for a routine execution retry. Each can change whether a packet remains recoverable, so the packet state must be established before an authorized account uses one.

Stopping verification before delivery

skip lets the OApp itself or its delegate bypass only the next inbound nonce when verification fails or must be cancelled. It is not the remedy for a packet that has already been verified and merely failed receiver execution. Once skipped, that payload cannot be recovered, which turns a temporary delay into a final decision for that nonce.

Removing or resetting stored payload state

clear removes a known verified payload when an execution error is unrecoverable or the packet must never run. It permanently ends retries for that stored message and emits PacketDelivered without calling the receiver. nilify instead marks a non-executed payload hash with the NIL value so the packet can be submitted again through the message library, a specialized response to disputed or disrupted verification.

Removing or resetting stored payload state: clear removes a known verified payload when an execution error is unrecoverable or the packet must never run. It permanently ends retries for that stored message and emits PacketDelivered without calling the receiver. nilify instead marks a non-executed payload hash with the NIL value so the packet can be submitted again through the message library, a specialized response to disputed or disrupted verification.

View image file

burn permanently blocks an eligible payload without requiring the original message bytes and applies only under its nonce condition relative to the lazy inbound nonce. Both nilify and burn are defensive edge controls rather than normal troubleshooting steps. When the evidence does not yet distinguish unverified, verified-failed and delivered states, an irreversible action would discard information needed for the correct branch.

Quick answers

May any account retry a verified Layer zero packet?

Yes. After failed execution leaves a verified payload stored, any account can call the Endpoint's lzReceive function with the matching origin, receiver, GUID and message bytes. The OApp itself or its authorized delegate controls administrative methods such as skip and clear. The retry must match the stored payload hash, and the receiver logic must accept the call.

Does retrying create a new nonce or GUID?

No. A destination retry reuses the origin tuple, receiver, nonce, GUID and message bytes of the verified packet. Those fields tie the call to its stored payload hash. A new source send would create a different packet identity and could duplicate the application intent instead of repairing the original execution.

Is a manual retry paid on the source or destination chain?

A direct retry is a destination-chain transaction, so the caller needs that chain's native token for gas and must provide any value required by the receiver call. The retry does not repeat the source send or its messaging fee. Its total cost depends on destination gas use, current gas conditions and any value forwarded to the receiver, so no fixed amount applies.

Are verified packets subject to a fixed retry deadline?

Layer zero V2 does not impose a fixed retry deadline while a verified payload remains stored and executable. Successful delivery or an authorized recovery control can change that status. Application state, permissions or contract code can also change before a later attempt, so the current payload status and receiver condition determine whether execution can succeed.

Could an EVM receive retry apply the same payload twice?

A reverted EVM execution rolls back the receiver's state changes and restores the payload for another attempt. After a successful call, the Endpoint removes the stored payload hash, so the same channel entry cannot execute again through the normal lzReceive path. Separate application actions should retain their own completion evidence.

Does PacketDelivered cover a later lzCompose call?

No. When emitted by a successful lzReceive transaction, PacketDelivered covers the receive stage but not a later composed action. The clear function can emit the same event without calling the receiver, so the transaction method must also be checked. A composed action has its own lzCompose execution and can fail independently after the receive call succeeds. In that case, retry the compose call with its original compose data rather than resending the source packet or rerunning the completed receive stage.

Why might ordered execution leave later messages waiting?

With ordered delivery configured, one failed receive can hold later ordered messages until it is resolved. Default execution is unordered, although the Endpoint still requires preceding nonces to be verified, skipped or already delivered before a higher nonce can advance the channel. Confirm both the ordered execution option and the destination OApp's ordering logic before attributing the delay to the later packet.

· updated