# Intrinsic gas too low: cause and fix

> The gas limit is below the minimum a transaction needs to start. See what intrinsic gas is, why a hardcoded limit causes it, and how it differs from out of gas.

Source: https://hashspan.dev/errors/intrinsic-gas-too-low

## Short answer

Every transaction needs a minimum amount of gas just to start: 21,000 for a plain transfer, more when it carries data or creates a contract. If the gas limit you set is below that, the node refuses it before anything runs. Do not set the limit by hand: let the client estimate it.

## What you will see

- `intrinsic gas too low`
- `The amount of gas (1000) provided for the transaction is too low.`
- `intrinsic gas too low: gas <your limit>, minimum needed <the minimum>`

## Where does it stop?

Figure: A transaction's path from your code to the node, the mempool, a block and a receipt. The node's check is marked in red with the error intrinsic gas too low, and the later steps are dashed: no hash and no receipt.

The node checks the gas limit before it accepts the transaction. If the limit is below the minimum, nothing runs and nothing is mined: no hash, no receipt and no gas spent.

## What is the minimum?

A standard ETH transfer [needs a gas limit of 21,000](https://ethereum.org/developers/docs/gas). That is the base every transaction pays. Data adds to it (16 gas for each non-zero byte, [EIP-2028](https://eips.ethereum.org/EIPS/eip-2028)), and so does creating a contract.

Figure: The least gas a transaction can start with: 21,000 for every transaction, plus calldata at 16 gas per non-zero byte, plus more for a contract creation. A gas limit of 20,999 is refused with intrinsic gas too low and 21,000 is accepted for a plain transfer.

This minimum is checked first, before the contract's code runs. The gas the code then uses is a separate matter: if the limit covers the start but not the work, that is [out of gas](https://hashspan.dev/errors/out-of-gas).

## Why does it happen?

- **A hardcoded limit.** A transfer's 21,000 copied onto a call that carries data.
- **A number from a tool argument.** An agent or a config sets `gas: 1000` and nobody compares it with the minimum.
- **A limit for one kind of transaction used for another.** A contract creation is more than a transfer.

## How do I fix it?

1. **Do not set `gas` unless you must.** With a local account, viem estimates the gas when you leave it out.
2. **If you set it, estimate first and add headroom:**

```ts

declare const account: `0x${string}`;
declare const to: `0x${string}`;
declare const data: `0x${string}`;
const publicClient = createPublicClient({ chain: mainnet, transport: http() });
const wallet = createWalletClient({ account, chain: mainnet, transport: http() });

// Estimate the gas, then add headroom: the state can change before the transaction is mined.
const gas = await publicClient.estimateGas({ account, to, data });
await wallet.sendTransaction({ to, data, gas: (gas * 120n) / 100n });
```

3. **Read the minimum from the error where the client prints it.** geth names it. If yours does not, estimate instead of guessing.

## What does it look like in a trace?

A refusal by the node: a `send` span that ends with an error and no hash.

<AttributeCard
span="send 31337"
status="bad"
rows={[
['error.type', 'IntrinsicGasTooLowError'],
['exception.message', 'The amount of gas (1000) provided for the transaction is too low.'],
['blockchain.tx.hash', 'not set'],
]}
caption="From the run above, with a limit of 1,000. exception.message appears only with errorMessages set to sanitized."
/>

By default only the error type is recorded, and for this refusal it is `IntrinsicGasTooLowError`. [Nonce too low](https://hashspan.dev/errors/nonce-too-low#what-does-it-look-like-in-a-trace) shows how to read the node's wording too.

## FAQ

### What is intrinsic gas?

The gas a transaction costs before its code runs. A standard ETH transfer takes 21,000 (ethereum.org). Data adds to it: a non-zero byte of calldata costs 16 gas (EIP-2028). geth also counts the access list and whether the transaction creates a contract.

### How is this different from out of gas?

Intrinsic gas too low is a refusal at the node: no hash, no gas spent. Out of gas happens after the transaction was mined, when the code uses up the limit, and the gas is paid. See the out of gas page.

### Does geth tell me the minimum?

Yes. Its error reads intrinsic gas too low: gas, then your limit, then minimum needed and the number. Anvil and viem print only the short form.
