EVM / SolidityRunbook 0/4 done
0x118cdaa7

EVM / Solidity Error 0x118cdaa7: OwnableUnauthorizedAccount

Error✕ Not retryable · fix the payloadSmart Contract
TL;DR · 10-second read

An onlyOwner function was called by an address that is not owner(). The data contains the caller; send from the owner account, or transfer ownership — and remember v5 requires an initialOwner in the constructor.

Identify: does your log match?

What you see · exact log / response
ContractFunctionExecutionError: The contract function "setFee" reverted.

Error: OwnableUnauthorizedAccount(address account)
                                (0x70997970C51812dc3A010C7d01b50e0d17dc79C8)

Raw revert data:
0x118cdaa700000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8

Version: viem@2.21.37
  1. High

    Calling from the wrong account

    The script or wallet uses a different signer than the deployer that owns the contract.

  2. Medium

    Owner set to the factory or deployer contract

    With OZ v5 Ownable(initialOwner), passing msg.sender inside a factory makes the factory the owner, not the EOA.

  3. Medium

    Ownership already transferred or renounced

    transferOwnership to a multisig or renounceOwnership() means the old key can no longer call admin functions.

Fix

Pass the intended owner explicitly (OZ v5)

✕ Broken · Solidity
contract Vault is Ownable {
    constructor() Ownable(msg.sender) {}
}
// deployed via a factory: owner == factory address
✓ Fixed · Solidity
contract Vault is Ownable2Step {
    constructor(address initialOwner) Ownable(initialOwner) {}
}
// factory: new Vault(msg.sender);

An explicit initialOwner makes ownership deterministic across factories and scripts. Ownable2Step requires the new owner to accept, avoiding typos.

Verify: reproduce it on purpose

Reproduce locally · cast
$ cast decode-error 0x118cdaa700000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8 --sig "OwnableUnauthorizedAccount(address)"

Run it against a dev environment to trigger 0x118cdaa7 on purpose and test your error handler.

Prevent

  • Use a multisig as owner in production.
  • Prefer Ownable2Step for transfers.
  • Log owner() in deploy scripts after deployment.

FAQ

How do I see who the owner is?

cast call <contract> "owner()(address)" --rpc-url $RPC_URL returns the current owner.

Why does OZ v5 Ownable require a constructor argument?

v5 removed the implicit msg.sender owner to prevent factory and proxy ownership mistakes. Pass initialOwner explicitly.

What about AccessControl roles?

AccessControl reverts with AccessControlUnauthorizedAccount(account, role), selector 0xe2517d3f. Grant the role with grantRole.

Related errors

Last verified 2026-10-18 · Source: 4byte/OpenChain signatures + OpenZeppelin v5 custom errors + Panic codes · Official docs ↗ · ~2,400 searches/mo