Diagnose the Root Cause of a Revert
Follow a failed Execution Trace to the deepest error, then verify the cause with timing data and execution context.
Case objective
Determine why a transaction failed, where the error originated, and whether the onchain inputs provide enough evidence to support that conclusion.
Example transaction and context
This case examines a failed Ethereum transaction:
0x3d48f58695be07b355ba5d5ca42e4a221f3008f63c055aa031b7f4b92b2eee2fOpen the transaction in Skylens · Verify it on Etherscan
The public error is Expired. The call targets 0x278d858f05b94576C1E6f73285886876ff6eF8D2 with entry selector 0x669dc5b6.
Questions to answer
- Which call node produced
Expired? - Was the failure caused by permissions, balance, slippage, or a deadline?
- What effects remain after the revert?
Investigation steps
- In Overview, confirm the status, From, To, selector, and revert message.
- In Execution Trace, follow failed nodes inward until you reach the first node that directly produces the error and has no deeper failed child.
- Record its displayed trace index, contract, inputs, return data, and parent call. Trace indexes can be regenerated between analysis versions, so preserve the address and selector as stable identifiers.
- In Source Debugger, inspect the time comparison at the failure point. If source is unavailable, use Bytecode Debugger to inspect the comparison before
REVERTand the relevant calldata. - Return to Balance Changes and State Changes to separate attempted internal behavior from final effects that survived execution.
Key evidence
| Evidence | Value | Meaning |
|---|---|---|
| Transaction execution time | 2026-03-03 14:40:11 UTC | Time the transaction was included |
| Deadline in calldata | 0x69a6f254 = 1772548692 | 2026-03-03 14:38:12 UTC |
| Time difference | 119 seconds | Execution occurred after the deadline |
| Failed contract | 0x278d858f05b94576C1E6f73285886876ff6eF8D2 | Direct transaction target |
| Entry selector | 0x669dc5b6 | Stable identifier even without a function name |
| Revert message | Expired | Consistent with the timing evidence |
| Gas | limit 600,000; used 148,785 | State reverted, but gas was still consumed |
The transaction executed 119 seconds after its deadline. If Source Debugger or Bytecode Debugger shows the failing comparison using that same deadline, the evidence confirms the cause without relying only on the error string.
Conclusion
The transaction executed 119 seconds after its deadline, and the target call returned
Expired. The revert message, deadline encoded in calldata, and execution time all agree: the deadline had passed. State changes were reverted, while the sender still paid for the gas consumed.
Caveats
- The deepest revert is not always the business root cause; an upper call may have constructed the invalid argument.
- A failed internal call does not always fail the whole transaction because callers can catch errors.
- A trace index is a UI navigation aid. Reports should also preserve the address, selector, and inputs.
- Internal events or transfers do not prove a final effect; verify Balance Changes and State Changes.
