AvaCloud

How to resend an ICM message?

It can be useful to resend an ICM message if the icm-relayer failed to processed it on the destination chain. This can happen for a variety of reasons, such as:

  • The relayer service was down when the message was sent.
  • A change in the source chain validator set caused the message signature to be invalid.
  • There was a bug in the relayer service that caused it to fail to process the message

To resend an ICM message, you can use the Teleporter Messenger contract's retrySendCrossChainMessage function.

Let's try resending an existing ICM message.

Get transaction logs

For this example, the source chain transaction is on the C-Chain and has the hash 0x7770fd801f2caf39c07f64941946b84e9d2fdbb1148e25e72560dc3cf4210dae

We can get the logs via the cast receipt command:

$ cast receipt \
  --rpc-url="https://api.avax-test.network/ext/bc/C/rpc" \
  0x7770fd801f2caf39c07f64941946b84e9d2fdbb1148e25e72560dc3cf4210dae \
  logs
[
	address: 0xEB9A66f680aEB6c9957D378dbD0c7323aFfB008B
	blockHash: 0x9793eb31b636fc3c3e62b10213b1fceffd8c48b0586ba329a05de90c35373c47
	blockNumber: 49432255
	data: 0x00000000000000000000000000000000000000000000000000470de4df820000
	logIndex: 0
	removed: false
	topics: [
		0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
		0x000000000000000000000000d2bbd2c9da58ec0b329fb85c802aee45fbcd523b
		0x0000000000000000000000000000000000000000000000000000000000000000
	]
	transactionHash: 0x7770fd801f2caf39c07f64941946b84e9d2fdbb1148e25e72560dc3cf4210dae
	transactionIndex: 0
 
	address: 0x253b2784c75e510dD0fF1da844684a1aC0aa5fcf
	blockHash: 0x9793eb31b636fc3c3e62b10213b1fceffd8c48b0586ba329a05de90c35373c47
	blockNumber: 49432255
	data: 0x0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054fbb000000000000000000000000eb9a66f680aeb6c9957d378dbd0c7323affb008ba0d897e580cef0346681be651d6a3e733de9b82e71eb79b06a3b3df8769da5fa00000000000000000000000036e9f643478f47a2306466b6a318de8577942d46000000000000000000000000000000000000000000000000000000000098968000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000c5c5e54dcf9e26e58eedc9640810d2519adaf38900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000d2bbd2c9da58ec0b329fb85c802aee45fbcd523b00000000000000000000000000000000000000000000000000470de4df820000
	logIndex: 1
	removed: false
	topics: [
		0x2a211ad4a59ab9d003852404f9c57c690704ee755f3c79d2c2812ad32da99df8
		0xf7724e43bd884a2a18c1eca59ce06074e92c699041d7311242ebddce014714a7
		0xa0d897e580cef0346681be651d6a3e733de9b82e71eb79b06a3b3df8769da5fa
	]
	transactionHash: 0x7770fd801f2caf39c07f64941946b84e9d2fdbb1148e25e72560dc3cf4210dae
	transactionIndex: 0
 
	address: 0x0200000000000000000000000000000000000005
	blockHash: 0x9793eb31b636fc3c3e62b10213b1fceffd8c48b0586ba329a05de90c35373c47
	blockNumber: 49432255
	data: 0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002cc0000000000057fc93d85c6d62c5b2ac0b519c87010ea5294012d1e407030d6acd0021cac10d5000002a200000000000100000014253b2784c75e510dd0ff1da844684a1ac0aa5fcf0000028000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000054fbb000000000000000000000000eb9a66f680aeb6c9957d378dbd0c7323affb008ba0d897e580cef0346681be651d6a3e733de9b82e71eb79b06a3b3df8769da5fa00000000000000000000000036e9f643478f47a2306466b6a318de8577942d46000000000000000000000000000000000000000000000000000000000098968000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000c5c5e54dcf9e26e58eedc9640810d2519adaf38900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000d2bbd2c9da58ec0b329fb85c802aee45fbcd523b00000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000000000000000000000
	logIndex: 2
	removed: false
	topics: [
		0x56600c567728a800c0aa927500f831cb451df66a7af570eb4df4dfbf4674887d
		0x000000000000000000000000253b2784c75e510dd0ff1da844684a1ac0aa5fcf
		0x695fc3e68ebf7712e57d6f0d31ef8108468e238572b5275e64ed3df72dd677ce
	]
	transactionHash: 0x7770fd801f2caf39c07f64941946b84e9d2fdbb1148e25e72560dc3cf4210dae
	transactionIndex: 0
 
	address: 0xEB9A66f680aEB6c9957D378dbD0c7323aFfB008B
	blockHash: 0x9793eb31b636fc3c3e62b10213b1fceffd8c48b0586ba329a05de90c35373c47
	blockNumber: 49432255
	data: 0xa0d897e580cef0346681be651d6a3e733de9b82e71eb79b06a3b3df8769da5fa00000000000000000000000036e9f643478f47a2306466b6a318de8577942d46000000000000000000000000d2bbd2c9da58ec0b329fb85c802aee45fbcd523b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000989680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000470de4df820000
	logIndex: 3
	removed: false
	topics: [
		0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52
		0xf7724e43bd884a2a18c1eca59ce06074e92c699041d7311242ebddce014714a7
		0x000000000000000000000000d2bbd2c9da58ec0b329fb85c802aee45fbcd523b
	]
	transactionHash: 0x7770fd801f2caf39c07f64941946b84e9d2fdbb1148e25e72560dc3cf4210dae
	transactionIndex: 0
]

Out of the multiple logs above, we are interested in the one with the topic SendCrossChainMessage:

$ cast 4byte-event 0x2a211ad4a59ab9d003852404f9c57c690704ee755f3c79d2c2812ad32da99df8
SendCrossChainMessage(bytes32,bytes32,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes),(address,uint256))

Specifically, the SendCrossChainMessage event consists of the following fields:

  • messageID bytes32 (topic1)
  • destinationBlockchainID bytes32 (topic2)
  • TeleporterMessage (uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes)
  • TeleporterFeeInfo (address,uint256)

Decode the TeleporterMessage data

The data field of this log contains the encoded TeleporterMessage and TeleporterFeeInfo structs.

We will only need the TeleporterMessage part to resend the ICM message. See the function definition for retrySendCrossChainMessage here

function retrySendCrossChainMessage(
        TeleporterMessage calldata message
    ) external;

We can decode the SendCrossChainMessage log event data using the cast decode-abi command:

$ cast decode-abi \
  --input "Function((uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes),(address,uint256))" \
  0x0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054fbb000000000000000000000000eb9a66f680aeb6c9957d378dbd0c7323affb008ba0d897e580cef0346681be651d6a3e733de9b82e71eb79b06a3b3df8769da5fa00000000000000000000000036e9f643478f47a2306466b6a318de8577942d46000000000000000000000000000000000000000000000000000000000098968000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000c5c5e54dcf9e26e58eedc9640810d2519adaf38900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000d2bbd2c9da58ec0b329fb85c802aee45fbcd523b00000000000000000000000000000000000000000000000000470de4df820000
 
(348091 [3.48e5], 0xEB9A66f680aEB6c9957D378dbD0c7323aFfB008B, 0xa0d897e580cef0346681be651d6a3e733de9b82e71eb79b06a3b3df8769da5fa, 0x36E9F643478F47a2306466b6A318de8577942d46, 10000000 [1e7], [], [(60, 0xC5c5E54dCf9e26e58eeDC9640810d2519adaf389)], 0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000d2bbd2c9da58ec0b329fb85c802aee45fbcd523b00000000000000000000000000000000000000000000000000470de4df820000)
(0x0000000000000000000000000000000000000000, 0)

The decoded TeleporterMessage fields are as follows:

// Represents a message sent or received by an implementation of {ITeleporterMessenger}.
struct TeleporterMessage {
    uint256 messageNonce;
    address originSenderAddress;
    bytes32 destinationBlockchainID;
    address destinationAddress;
    uint256 requiredGasLimit;
    address[] allowedRelayerAddresses;
    TeleporterMessageReceipt[] receipts;
    bytes message;
}

Resend the ICM message

Import a wallet for use with the source chain:

$ cast wallet import my_wallet --interactive
 
$ cast wallet list
my_wallet (Local)
 
$ cast wallet address --account my_wallet
0x5829c85e4c68c4f799EC3D4B68D3C4950fa2E815

Then use the cast send command to call the retrySendCrossChainMessage function on the Teleporter Messenger contract with the decoded TeleporterMessage data:

$ cast send \
  --account my_wallet \
  --rpc-url="https://api.avax-test.network/ext/bc/C/rpc" \
  0x253b2784c75e510dD0fF1da844684a1aC0aa5fcf \
  "retrySendCrossChainMessage((uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))" \
  "(348091, 0xEB9A66f680aEB6c9957D378dbD0c7323aFfB008B, 0xa0d897e580cef0346681be651d6a3e733de9b82e71eb79b06a3b3df8769da5fa, 0x36E9F643478F47a2306466b6A318de8577942d46, 10000000, [], [(60, 0xC5c5E54dCf9e26e58eeDC9640810d2519adaf389)], 0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000d2bbd2c9da58ec0b329fb85c802aee45fbcd523b00000000000000000000000000000000000000000000000000470de4df820000)"
 
status               1 (success)
transactionHash      0x17be2f94f60c0290c7af5757b6b62f9e9b058de267b2342e385c1fbd94f2e0c3

The transaction is shown on the explorer

icm-relayer response

After a short while, the icm-relayer should pick up the resent ICM message and process it on the destination chain. You can check the relayer logs to confirm that the message was processed successfully.

2026-01-09 13:38:56.977 info {
  "level": "info",
  "timestamp": "2026-01-09T18:38:56.977Z",
  "logger": "icm-relayer",
  "caller": "relayer/message_coordinator.go:85",
  "msg": "Unpacked warp message",
  "sourceBlockchainID": "yH8D7ThNJkxmtkuv2jgBa4P1Rn3Qpr4pPr7QYNfcdoS6k6HWp",
  "originSenderAddress": "0xEB9A66f680aEB6c9957D378dbD0c7323aFfB008B",
  "destinationBlockchainID": "2Dqbd3m59HhhvBCPYZ59gY5PGNaGvQXoGBQuz2oFfDqLio5h7b",
  "destinationAddress": "0x36E9F643478F47a2306466b6A318de8577942d46",
  "warpMessageID": "oQe6MSiftiFYUm4C7TY92Gn6ZjHS1L9nB6Eetg3cytxarM1SB",
  "foundAppRelayer": true
} 
 
2026-01-09 13:38:56.977 info {
  "level": "info",
  "timestamp": "2026-01-09T18:38:56.977Z",
  "logger": "icm-relayer",
  "caller": "relayer/message_coordinator.go:260",
  "msg": "Registering message handler",
  "relayerID": "0xdcc351408f480cb9365772e3d46b9cb1dedad9b7c38b4a4d05f4f0fd610bc771",
  "warpMessageID": "oQe6MSiftiFYUm4C7TY92Gn6ZjHS1L9nB6Eetg3cytxarM1SB",
  "sourceBlockchainID": "yH8D7ThNJkxmtkuv2jgBa4P1Rn3Qpr4pPr7QYNfcdoS6k6HWp",
  "originSenderAddress": "0x253b2784c75e510dD0fF1da844684a1aC0aa5fcf",
  "originTxID": "0x17be2f94f60c0290c7af5757b6b62f9e9b058de267b2342e385c1fbd94f2e0c3"
} 
 
2026-01-09 13:38:56.977 info {
  "level": "info",
  "timestamp": "2026-01-09T18:38:56.977Z",
  "logger": "icm-relayer",
  "caller": "relayer/application_relayer.go:237",
  "msg": "Relaying message",
  "relayerID": "0xdcc351408f480cb9365772e3d46b9cb1dedad9b7c38b4a4d05f4f0fd610bc771"
} 
 
2026-01-09 13:38:56.988 info {
  "level": "info",
  "timestamp": "2026-01-09T18:38:56.988Z",
  "logger": "icm-relayer",
  "caller": "teleporter/message_handler.go:225",
  "msg": "Message already delivered to destination.",
  "warpMessageID": "oQe6MSiftiFYUm4C7TY92Gn6ZjHS1L9nB6Eetg3cytxarM1SB",
  "teleporterMessageID": "2sygxUowKpLQwPo7gKSiFgQqvcnyp7YJDrt87tiny84XYH7TBQ",
  "destinationBlockchainID": "2Dqbd3m59HhhvBCPYZ59gY5PGNaGvQXoGBQuz2oFfDqLio5h7b"
} 
 
2026-01-09 13:38:56.988 info {
  "level": "info",
  "timestamp": "2026-01-09T18:38:56.988Z",
  "logger": "icm-relayer",
  "caller": "relayer/application_relayer.go:251",
  "msg": "Message should not be sent"
} 

For this example, since this message was alerady processed on the destination chain, the relayer correctly identifies that and does not attempt to resend it.


If you need more help, explore our other articles or reach out to our support team via chat or email [email protected]. All examples provided are for demonstration purposes only.

Learn More About AvaCloud | Download Case Studies | Schedule an AvaCloud Demo

On this page