Skip to content
Last updated: February 06, 2026

SCWE-146: Improper Use of try/catch Leading to Silent Failures

Stable Version v1.0

This content is in the version-(v1.0) and still under active development, so it is subject to change any time (e.g. structure, IDs, content, URLs, etc.).

Send Feedback

Relationships

Description

Solidity 0.6+ try/catch allows catching reverts from external calls. If the catch block does not properly handle the failure—e.g., proceeds without reverting, leaves state inconsistent, or swallows the error without logging—the contract can continue execution under incorrect assumptions. Silent failures can lead to fund loss, corrupted state, or exploitable inconsistencies.

Remediation

  • In catch blocks, either revert with a clear message or update state to reflect the failure (e.g., mark operation as failed, emit event).
  • Avoid proceeding with critical logic when the external call failed unless the failure is explicitly handled and documented.

Examples

Vulnerable

pragma solidity ^0.8.0;

contract Aggregator {
    function swap(address router, bytes calldata data) external {
        try IRouter(router).swap(data) returns (uint256 amountOut) {
            transferToUser(msg.sender, amountOut);
        } catch {
            // Silent: user gets nothing but tx succeeds; state may be inconsistent
        }
    }
}

Fixed

function swap(address router, bytes calldata data) external {
    try IRouter(router).swap(data) returns (uint256 amountOut) {
        transferToUser(msg.sender, amountOut);
    } catch {
        revert("Swap failed");
    }
}
Fix: Revert in the catch block so the transaction fails. Avoid catch (bytes memory reason) with string concatenation—reason may be a custom error selector, not a string.