unionlabs/union · error · anyhow::Error
wait_for_packet_recv failed: {:?}
Error message
wait_for_packet_recv failed: {:?} What it means
After a successful packet send, `send_and_recv` waits on `destination_chain.wait_for_packet_recv(packet_hash, timeout)`; this error means the receiving chain did not observe a packet-recv event for that hash within the timeout. Almost always a relaying/latency problem, not a code failure.
Source
Thrown at tools/union-test/src/lib.rs:712
println!("send_ibc_tx succeeded with hash: {:?}", hash);
hash
}
Err(e) => {
anyhow::bail!("send_ibc_transaction failed: {:?}", e);
}
};
println!(
"Packet sent from {} to {} with hash: {}",
source_chain.chain_id(),
destination_chain.chain_id(),
packet_hash
);
match destination_chain
.wait_for_packet_recv(packet_hash, timeout)
.await
{
Ok(evt) => Ok(evt),
Err(e) => anyhow::bail!("wait_for_packet_recv failed: {:?}", e),
}
}
pub async fn send_and_recv_and_ack<Src: ChainEndpoint, Dst: ChainEndpoint>(
&self,
source_chain: &Src,
contract: Src::Contract,
msg: Src::Msg,
destination_chain: &Dst,
timeout: Duration,
signer: &Src::ProviderType,
) -> anyhow::Result<(helpers::PacketRecv, helpers::PacketAck)> {
let (packet_hash, _height) = match source_chain
.send_ibc_transaction(contract.clone(), msg.clone(), signer)
.await
{
Ok(hash) => {
println!("send_ibc_tx succeeded with hash: {:?}", hash);View on GitHub (pinned to 031785bb6d)
Solutions
- Increase the `timeout` passed to send_and_recv
- Check that the relayer is running and healthy between the two chains
- Verify the IBC client/channel are open and not expired or errored
- Confirm the destination chain is producing blocks
Example fix
// before suite.send_and_recv(src, c, m, dst, Duration::from_secs(120), &signer).await?; // after suite.send_and_recv(src, c, m, dst, Duration::from_secs(900), &signer).await?;
Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: relayer reachable / channels open before waiting for recv let _ = destination_chain.query_channel_end(&port_id, &channel_id).await?; // errors early if the path is broken
Try / catch
match suite.send_and_recv(src, c, m.clone(), dst, timeout, &signer).await {
Ok(r) => Ok(r),
Err(e) if e.to_string().contains("wait_for_packet_recv failed") => {
check_repeater_health();
suite.send_and_recv(src, c, m, dst, timeout * 2, &signer).await
}
Err(e) => Err(e),
} Prevention
- Start relayers as a setup step and health-check them before packet tests
- Size timeouts to relayer latency plus proof verification, with margin
- Monitor client/channel expiry so packets aren't silently dropped
When it happens
Trigger: Relayer between the chains stopped or slow; destination chain halted; timeout shorter than relayer latency plus proof-verification time; broken/expired client or channel so the relayer skips the packet.
Common situations: Devnet relayer process not started; timeouts tuned for fast local chains reused on slower testnets; client expiry after chain downtime.
Related errors
- wait_for_packet_ack failed: {:?}
- wait_for_packet_timeout failed: {:?}
- wait_for_update_client failed: {:?}
- timed out after {:?}
- timed out after {:?}
AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16).
Data as JSON: /api/errors/99ef2d448c348298.
Report an issue: GitHub.