VIEW THIS AS

Auto mode follows the Route Engine until you choose a viewpoint.

YOU ARE HERE

ROUTE CHECK

CONNECTED TO

WHAT NEXT

Use the canonical route for this room, or HELP if you are unsure.

Diagnosing Failed Blockchain Transactions: Rejection, Revert and Call Boundaries

Three students in school uniforms work through open books at a classroom table, with textbooks and stationery nearby and study notes on the whiteboard behind them.

中文版 · Blockchain learning guide · Previous article

Blockchain learning · Article BC039

Three students in school uniforms work through open books at a classroom table, with textbooks and stationery nearby and study notes on the whiteboard behind them.
Study photograph for illustration; it does not establish that the pictured students are studying blockchain.

A transaction described as failed may never have entered a block, may have been dropped from one node’s candidate pool, or may have been included and executed unsuccessfully. Those cases have different evidence and different effects. A red label is not enough to decide whether an application record, sender nonce or fee changed.

This guide uses a controlled execution worksheet to classify outcomes before proposing a fix. It also examines a less obvious case: an inner call fails, the outer program handles that failure and the overall transaction succeeds. The goal is accurate diagnosis, not instructions to resubmit real transactions.

Choose your reading route

In this guide

Start with the three questions about inclusion, top-level outcome and affected state. Then compare the supplied success, REVERT and out-of-gas cases. Read the nested-call example before assuming that one error message determines the result of an entire transaction.

All accounts, values and resource totals are synthetic. The worksheet follows selected ordinary EVM-style call distinctions but is not a complete Ethereum implementation. It excludes contract creation, delegation authorizations, transferred value, blob charges and unrelated provider fees.

Back to contents · Next section

1. Classify the stage before naming the cause

Ask first whether the candidate was included in a particular selected block. A submission error or local pool disappearance is not, by itself, evidence of included execution failure.

If inclusion is established, ask about the transaction’s top-level execution status. Then ask which state changes belong to the transaction envelope, which belong to application execution and which belong to an inner call frame.

This order prevents an easy mistake: starting with a guessed cause such as “not enough gas,” then interpreting every observation to fit it. The same user-facing failure word can cover invalid input, a missing dependency, a failed application condition or a nested error that the program deliberately handled.

A useful first report names the known stage and the missing evidence. “This endpoint rejected the submission; no inclusion has been established” is more precise than “the blockchain reverted it.” The latter claims an execution event that may never have happened.

Back to contents · Next section

2. Use an identified receipt, not a floating status word

EIP-658, created 30 June 2017 and marked Final, defines transaction receipt status indicating top-level success or failure in its applicable Ethereum context. That status is valuable evidence, but it does not contain a full explanation of every application condition.

An included failure can have a receipt. Failure therefore does not mean the transaction vanished from the block. Conversely, absence of a receipt from one endpoint at one moment is not proof that no other observer has seen inclusion.

Record the network, transaction identifier, containing block identity and the endpoint’s selected-chain context. A receipt attached to a branch no longer selected is different evidence from a receipt in the currently selected history.

A success status also does not prove that the human obtained the intended business result. A program may legitimately return without making the desired update, or handle an inner failure through an alternative path. Read the relevant application state and execution behavior as well as the top-level status.

Back to contents · Next section

3. The worksheet separates three kinds of state

Each main case starts independently from the same supplied snapshot. Sender A has 200,000 invented credits and ordinary next nonce 7. The application record value is 8. The intended successful call changes that value to 9.

The included cases use nonce 7; Case A explicitly uses an incorrect candidate nonce of 6 instead. The transaction has a gas limit of 50,000 and an effective execution price of 2 invented credits per gas. We supply final charged-gas totals for each outcome rather than derive them from bytecode. All required affordability and ordinary transaction-validity conditions hold in the included cases.

There is no value transfer to another account. The only sender balance change in these cases is the supplied execution fee. The resource totals already represent the relevant final accounting; no additional refund, floor or separate fee component is to be added by the reader.

Track three fields separately: sender balance, sender next nonce and application value. The point is to see why a failed application update does not automatically return every field in the whole transaction process to its earlier value.

The Geth v1.16.5 state-transition implementation provides a concrete versioned reference: the ordinary call path advances the sender nonce before the EVM call. We use that narrow distinction, not a claim that the cited version covers every future fork or every account mechanism.

Back to contents · Next section

4. Case A: rejection before included execution

In this independent case, the candidate fails a required pre-execution validity condition and is not included. Specifically, its candidate nonce is 6 while the supplied state requires 7. The supplied case establishes rejection rather than merely an unexplained delay.

No included execution is performed for this candidate. Under the worksheet, sender balance remains 200,000, next nonce remains 7 and application value remains 8. There is no on-chain execution fee for this rejected attempt in the model.

That result should not be generalised to every object with a future nonce. A node may retain a candidate for later under its pool policy; retention and immediate execution eligibility are different. Here the evidence explicitly says the attempt was rejected and not included.

Do not describe the unchanged application value as “rolled back” when no application execution began. “No accepted application transition occurred” states the evidence more accurately.

Back to contents · Next section

5. Case B: local disappearance without a chain outcome

Suppose a node previously retained the candidate, then no longer reports it in its pool. No inclusion evidence is supplied. This is a local observation, not a complete execution result.

The candidate may have been evicted, replaced under policy, become ineligible or disappeared from that endpoint’s view for another reason. The investigation must obtain the relevant evidence rather than choose one explanation automatically.

For this case, we cannot infer a new sender balance, nonce or application value merely from disappearance. If the worksheet additionally tells us that the selected chain state is unchanged, those fields remain at the initial snapshot. Without that additional fact, the correct answer is that the chain outcome has not been established.

Likewise, another candidate may have used the same sender position elsewhere. A local label such as dropped does not tell us which transaction, if any, the selected chain accepted. The mempool lesson provides the observation framework; here the important point is to avoid inventing a rollback from a missing pool entry.

Back to contents · Next section

6. Case C: an included successful call

The successful case is included and has a supplied final charged-gas amount of 25,000. At price 2, its fee is 50,000 invented credits.

The resulting sender balance is 200,000−50,000=150,000. The ordinary sender nonce advances from 7 to 8. The application update succeeds, so its value becomes 9.

This is the baseline against which to compare the failed execution cases. All three tracked fields change, but for different reasons: a processing charge, consumption of the ordinary sender sequence position and a successful application write.

The worksheet supplies a top-level success outcome and the application update. In a real diagnosis, one should not infer the specific value 9 from a success status alone. The relevant code path and state evidence must support that additional claim.

Back to contents · Next section

7. Case D: included top-level REVERT

Now use an independent execution from the original snapshot. The application attempts its operation but the top-level call reaches a REVERT condition. The supplied final charged gas is 30,000.

The application value returns to 8 under this case’s execution rollback. The fee is 30,000×2=60,000, leaving sender balance 140,000. The ordinary sender nonce is 8, not 7. The transaction remains an included transaction with a failed top-level execution outcome.

EIP-140, created 6 February 2017 and marked Final, specifies REVERT behavior that rolls back affected execution changes without inherently consuming all remaining gas. It does not mean the processing already accounted for becomes free.

The important boundary is what rolls back. “The application write did not persist” is correct here. “Nothing happened anywhere” is not: the selected history includes the transaction, the sender position was consumed and the supplied fee was charged.

A trace may show a temporary write during execution that is later reverted. That trace observation is not proof that the final persistent application value changed. Distinguish intermediate execution steps from the resulting selected state.

Back to contents · Next section

8. Case E: top-level out-of-gas failure

In another independent case, the top-level execution exhausts the supplied transaction gas budget. The worksheet gives final charged gas as the full 50,000, with no extra accounting adjustments.

The fee is 50,000×2=100,000, leaving sender balance 100,000. The sender nonce advances to 8. The failed application execution leaves its final value at 8.

This differs from the REVERT case’s supplied 30,000 charge, even though both have failed top-level execution and the same final application value. A generic failed label cannot distinguish their resource outcomes.

The Geth v1.16.5 EVM call implementation separates execution-reverted errors from other exceptional call errors when handling remaining gas and restoring the call snapshot. This supports examining the actual failure category and frame, rather than treating every error as identical.

Do not extend this top-level worksheet into “any inner out-of-gas consumes the whole transaction limit.” Inner calls have their own allocated execution context, and an outer call can have different remaining resources and handling behavior. The next case makes that boundary explicit.

Back to contents · Next section

9. Case F: an inner failure is handled by the outer program

Add a separate outer application field called handled, initially false. The outer program calls a child operation that attempts to change the child record from 8 to 9. The child reverts, so the child record remains 8.

The supplied outer code catches that external-call failure, sets handled to true and completes successfully. The overall transaction therefore has top-level success in this scenario, even though a trace contains a failed child call.

For this independent case, final charged gas is supplied as 35,000. At price 2, the fee is 70,000, sender balance becomes 130,000 and ordinary next nonce becomes 8. The final application facts are child value 8 and outer handled true.

The Solidity 0.8.30 control-structures reference explains exception handling for external calls and contract creation. Our case assumes the relevant failure is caught and the remaining outer execution succeeds; it does not claim that every failure can be caught at every point.

If instead the outer program propagates the error and the top-level execution reverts, the result is a different case. The call boundary and error-handling path are part of the evidence, not optional detail to ignore after seeing the first error message.

Back to contents · Next section

10. Error text is a clue, not an authenticated diagnosis

An error string or decoded custom error can help identify a condition. It is not a complete proof of which component caused the problem or whether the entire transaction failed.

The Solidity 0.8.30 ABI specification warns that error data can propagate through calls and can be imitated by another contract. A familiar error name should therefore be interpreted with the call trace, code and execution context.

A useful diagnosis identifies the relevant call frame, the condition evaluated there and how the result propagated. It also distinguishes a deliberate application refusal from resource exhaustion or another exceptional condition.

This is not a request to trust any arbitrary trace service. Record the source and limitations of the trace, then compare it with the included transaction, receipt and resulting state. A decoded explanation is an interpretation layered on execution evidence.

Back to contents · Next section

11. Build an evidence-first diagnosis

For a real report, organise the investigation around a few concrete questions rather than starting with a live retry.

  • Which network, transaction identifier and block context are being examined?
  • Is inclusion established, or do we have only submission and pool observations?
  • What is the top-level receipt status under the applicable rules?
  • Which call frame first reports the relevant failure, and is it caught or propagated?
  • Which application changes were reverted, and which transaction-level effects remain?
  • What are the measured charged gas and effective price for the relevant fee component?
  • Does the state query refer to the same selected history as the receipt and trace?
  • Which uncertainty remains because data or context is missing?

For Case D, the concise conclusion is: “Included top-level REVERT; application value remains 8, ordinary sender nonce is 8, and the supplied processing fee leaves balance 140,000.” That is more useful than “the transaction did nothing.”

For Case F, say: “The child update reverted, but the outer program handled it and completed; child value remains 8 and handled becomes true.” Do not replace this with “everything failed” merely because a child frame is marked red.

Back to contents · Next section

12. Why an automatic retry can answer the wrong question

Repeating an instruction is not a diagnosis. The relevant state, nonce, deadline or application conditions may have changed since the first attempt. A later transaction can therefore execute a different path even if the visible user request looks similar.

After an included failure in the ordinary model, the sender nonce has advanced. Treating the old sequence position as unused contradicts the supplied state. Conversely, local disappearance alone does not establish whether the position was consumed elsewhere.

A retry can also be inappropriate when the top-level transaction succeeded through a fallback path. Before deciding what another action should do, establish the actual application outcome and the user’s intended next step.

This lesson deliberately stops at the evidence record. It does not recommend fee increases, nonce replacement or resubmission on a live network. The transferable skill is knowing which facts must be established before anyone chooses a consequential next action.

Back to contents · Next section

13. Exercise: classify the six cases

Use the independent snapshots and supplied resource totals. Do not carry one case’s ending balance into the next.

  1. A candidate is definitely rejected before inclusion. Which of the three tracked fields changes in the worksheet?
  2. A node stops reporting a pending candidate, but no chain-state evidence is supplied. Can you conclude that the application rolled back?
  3. The successful included case uses 25,000 charged gas. What are balance, next nonce and application value?
  4. The top-level REVERT case uses 30,000. What remains and what changes?
  5. The top-level out-of-gas case uses 50,000. How does its balance compare with the REVERT case?
  6. The child reverts, the outer call catches it and succeeds with 35,000 charged gas. Can top-level success coexist with the unchanged child value?
  7. Does a familiar decoded error name alone prove the identity of the failing component?

Answers and reasoning

  1. None: balance 200,000, next nonce 7 and application value 8. No included execution occurred in this supplied case.
  2. No. Local pool absence does not establish an execution outcome or a state rollback.
  3. Balance 150,000, next nonce 8 and value 9. The fee is 50,000.
  4. Application value remains 8; balance becomes 140,000 and next nonce becomes 8. The application rollback does not erase the supplied transaction-level effects.
  5. Balance becomes 100,000, which is 40,000 lower than the REVERT case’s 140,000 because the supplied charged gas is 20,000 higher at price 2.
  6. Yes. Balance is 130,000, next nonce 8, child value 8 and handled true. The outer success does not make the failed child update persist.
  7. No. Error data needs code, call-frame and context evidence; it may be propagated or imitated.

Extension: same application state, different history

Cases A, D and E all leave application value 8, but their sender fields differ. A leaves balance 200,000 and nonce 7; D leaves 140,000 and 8; E leaves 100,000 and 8.

Therefore, querying only the application value cannot determine whether a candidate was rejected, reverted after inclusion or exhausted the top-level budget. Different histories can lead to the same application snapshot.

Back to contents · Next section

14. Frequently asked questions

Can a failed transaction be in a valid block?

Yes, in the applicable execution model an included transaction can have failed application execution while remaining a validly processed transaction. Do not confuse transaction-validity requirements with successful application behavior.

Does REVERT refund everything?

No. It rolls back the affected execution changes under its rules. It does not make all already charged processing disappear or universally restore transaction-level fields.

Does receipt success mean every nested call succeeded?

No. The outer program may handle an inner failure and complete. Inspect the relevant call and application outcome.

Is no receipt the same as failure?

No. The endpoint may not have inclusion information, the candidate may still be pending, or the observation may otherwise be incomplete. Establish context before classifying it.

Back to contents · Next section

15. Sources and next reading

Sources checked on 12 October 2026, Singapore time. Implementation references are pinned to Geth v1.16.5 and Solidity 0.8.30; they are not claims about every network, transaction type or future rule set.

Review gas accounting for the distinction between limits, charged use and unit price. Review storage and events to compare final state with intermediate or historical observations. Continue to oracles for failures that arise at the boundary between on-chain rules and external information.

Back to contents