Private Bundle Debugging: Common Failure Modes
**Answer first** — A private bundle that doesn't land in the next block has missed *inclusion*. Inclusion misses come in two flavours: **rejected by relay** (the relay refused to f

Answer first — A private bundle that doesn't land in the next block has missed inclusion. Inclusion misses come in two flavours: rejected by relay (the relay refused to forward your bundle to builders) and rejected by builder (the relay forwarded it, no builder included it). The first kind has a clear error response; the second kind is silent. The eight most common causes, in roughly the order you should check them: stale fee model, hint mismatch (e.g. forgotten revertingTxHashes), simulation drift between simulate and send, target-block slippage, latency to relay, builder rate limiting, payload encoding error, and outright builder coverage gaps. Each has a distinct signature in your logs. The diagnostic tree below tells you which to suspect based on what you actually see, instead of guessing.
Mastery path
- What is MEV?
- Backrun vs sandwich strategy
- Inclusion probability 101
- Fixing failed bundles guide
- Private bundle debugging (current)
What "the bundle didn't land" actually tells you
The receipt path for a private bundle goes:
- Your client serialises the bundle and sends it to a relay (
relay.flashbots.net,rpc.titanbuilder.xyz, etc.). - The relay validates schema, runs simulation, and forwards to participating builders.
- Builders include your bundle if it improves their block value above the next-best alternative.
- The proposer publishes whichever builder's block they were paid most for.
A miss can happen at step 2 (loud — relay returns an error), step 3 (mostly silent — relay accepted, no builder included), or step 4 (silent — wrong builder won the slot). Most operators see "the bundle didn't land" and assume the cause is uniform. It almost never is.
The eight failure modes
1. Stale fee model
Symptom: simulator shows the bundle as profitable, relay accepts, no builder includes.
Cause: between simulate and send, base fee shifted enough that your priority fee is no longer competitive.
Fix: re-query eth_feeHistory immediately before signing the bundle; reject if the fee at signing time differs from simulation by more than a configured threshold. On Polygon and busy mainnet hours, fees can shift 20–30% within a single block.
2. Hint mismatch
Symptom: relay returns 400 / "invalid hint" / "unsupported parameter."
Cause: you sent a hint the relay doesn't support, or forgot a hint the relay requires. Common offenders: revertingTxHashes for txs that may revert; minTimestamp / maxTimestamp; replacementUuid for resubmissions.
Fix: check the relay's documented schema for the version you're targeting. Most relays accept extra fields silently; some reject. Test with a canary bundle on every relay before deploying.
3. Simulation drift
Symptom: simulator green, real send reverts on inclusion.
Cause: state changed between your eth_callBundle simulate and the actual block. Common in DEX backruns: the pool ticks moved, the price you simulated against is no longer current.
Fix: simulate against the target block's expected state, not the current head. For 12-second mainnet slots this means pulling current state, applying the trigger tx in your sim, then layering your backrun. If your sim doesn't model the trigger, your sim is lying.
4. Target-block slippage
Symptom: bundle accepted, included one block later than targeted, profit substantially lower than simulated.
Cause: your bundle had a target block but the relay or builder pushed it back. Often happens during high-demand slots when the proposer takes a different builder's block.
Fix: set a tight targetBlockNumber and a maxBlockNumber only one or two blocks ahead. Better to miss than to land late at a worse price. Some strategies are first-block-only — encode that explicitly.
5. Latency to relay
Symptom: correlates with time of day; bundle misses cluster around your worst-latency hours.
Cause: RTT to the relay is high enough that your bundle arrives after the builder has already locked the block.
Fix: measure p95 RTT to each relay you use. Anything over ~150 ms on mainnet is questionable; over ~300 ms is broken. Move your sender closer (different region, different cloud provider) or switch relays. Run the WSS latency test periodically.
6. Builder rate limiting
Symptom: 429 Too Many Requests, 503 Service Unavailable, or silent drops above a certain rate.
Cause: you crossed the relay's rate limit. Free tiers cap aggressively; even paid tiers cap on bundle-submission rate per second.
Fix: check your tier limits, batch submissions if your strategy generates many candidates per second, and back off cleanly on 429. If you genuinely need more rate, upgrade or fan out across multiple relays for natural rate distribution.
7. Payload encoding error
Symptom: relay returns "invalid bundle," "malformed transaction," or 422.
Cause: wrong RLP encoding, missing chainId, EIP-1559 vs legacy mismatch, signature malformed.
Fix: decode your serialised bundle with a fresh tool (e.g. cast tx --decode) and compare to what you expected. Common gotcha: signing with the wrong chainId after copy-pasting code from a tutorial. Also: some relays require type-2 (EIP-1559) only; legacy txs are silently dropped.
8. Builder coverage gap
Symptom: bundle accepted by relay, no builder included, no specific error.
Cause: the relay you submitted to doesn't have a participating builder who won the next slot. Single-relay submission has this risk on every block.
Fix: fan out to at least four builders (Flashbots, Titan, beaverbuild, rsync-builder is the modern default). Track which relay landed each successful bundle; over time, weight your fan-out toward the winners. The FRB Agent does this fan-out and weight adjustment automatically.
Diagnostic flow
When a bundle misses, walk the flow in this order:
- Did the relay return an error? → check error code; map to failure mode 2, 6, or 7.
- No relay error, no inclusion? → check
eth_callBundlere-simulation against the actual block that was mined. If sim now says revert → mode 3 (drift). If sim says profit but you weren't included → modes 1, 4, or 8. - Latency histogram for the failed bundles. → if p95 latency was elevated → mode 5.
- Inclusion-rate by relay over the last N bundles. → if one relay's rate has collapsed → mode 8 (that relay's builder coverage has slipped).
What to log so debugging is possible
- Bundle submission timestamp + relay + tier
- Simulated profit (sim hash + result)
- Target block + max block
- Relay response (status code + body excerpt)
- Inclusion outcome: included? at what block? what gas paid? realised profit?
- Latency: time from local "decision to send" → relay accept → block mined
This is enough state to populate a daily inclusion-rate-by-cause dashboard. Most "FRB isn't working" tickets resolve in one query against a log set this complete.
When to fix the strategy vs the infra
A consistent gap between simulated and realised profit (>10%, persistent across days) is a strategy issue — the model is wrong about something. A consistent gap between bundles-submitted and bundles-included (<60% inclusion on a strategy that expects 80%+) is an infra issue — relay coverage, latency, or fee model.
The diagnostic flow above tells you which side to look at first. Looking at the wrong side first is how operators waste weeks tuning a strategy that was never the problem.
Related
Step after reading
Launch FRB dashboard
Connect your wallet, pair the node client with a 6-character PIN, and assign the contract mentioned above.
Need the signed build?
Download & verify FRB
Grab the latest installer, compare SHA‑256 to Releases, then follow the Safe start checklist.
Check Releases & SHA‑256Related Articles
Further reading & tools
Discussion
No notes yet. Add the first observation, or share the link with your team on X (@MCFRB).