FuelLabs/fuels-ts · error · FuelError
GAS_LIMIT_TOO_LOW
GAS_LIMIT_TOO_LOW
Error message
Gas limit '${setGasLimit}' is lower than the required: '${requiredGasLimit}'. What it means
Thrown by setAndValidateGasAndFeeForAssembledTx when a caller-supplied setGasLimit (for a Script transaction) is less than the gas the node estimates is required to execute the script (transactionRequest.gasLimit at that point). The guard prevents submitting a script that will run out of gas on-chain. It only applies to Script-type requests (create/upgrade txs are exempt).
Source
Thrown at packages/account/src/providers/assemble-tx-helpers.ts:72
};
export const setAndValidateGasAndFeeForAssembledTx = async <T extends TransactionRequest>(params: {
transactionRequest: T;
provider: Provider;
gasPrice: BN;
setGasLimit?: BigNumberish;
setMaxFee?: BigNumberish;
}): Promise<T> => {
const { gasPrice, transactionRequest, setGasLimit, setMaxFee, provider } = params;
const gasLimitSpecified = isDefined(setGasLimit);
const maxFeeSpecified = isDefined(setMaxFee);
const isScriptTx = transactionRequest.type === TransactionType.Script;
if (gasLimitSpecified && isScriptTx) {
const requiredGasLimit = transactionRequest.gasLimit;
if (bn(setGasLimit).lt(bn(requiredGasLimit))) {
throw new FuelError(
ErrorCode.GAS_LIMIT_TOO_LOW,
`Gas limit '${setGasLimit}' is lower than the required: '${requiredGasLimit}'.`
);
}
transactionRequest.gasLimit = bn(setGasLimit);
}
if (maxFeeSpecified) {
const requiredMaxFee = transactionRequest.maxFee;
if (bn(setMaxFee).lt(requiredMaxFee)) {
throw new FuelError(
ErrorCode.MAX_FEE_TOO_LOW,
`Max fee '${setMaxFee}' is lower than the required: '${requiredMaxFee}'.`
);
}
transactionRequest.maxFee = bn(setMaxFee);View on GitHub (pinned to b3f37c91ac)
Solutions
- Omit setGasLimit to let the SDK estimate and set the required gas automatically.
- If you must set it, first read transactionRequest.gasLimit (after estimation) and pass a value >= it.
- Re-estimate via provider.estimateTxGas before specifying setGasLimit.
- Add a safety margin: setGasLimit = bn(estimatedGasLimit).mul(12).div(10).
Example fix
// before
const res = await account.assembleTx({ transactionRequest, setGasLimit: 100 });
// after — let the SDK estimate, or pass a value >= required
const { gasUsed } = await provider.estimateTxGas(transactionRequest);
const res = await account.assembleTx({
transactionRequest,
setGasLimit: bn(gasUsed).mul(12).div(10), // >= required
}); Defensive patterns
Strategy: validation
Validate before calling
import { bn } from '@fuel-ts/math';
function validateGasLimit(setGasLimit, requiredGasLimit) {
if (bn(setGasLimit).lt(bn(requiredGasLimit))) {
throw new Error(`Gas limit must be >= ${requiredGasLimit.toString()}`);
}
} Type guard
function gasLimitIsSufficient(setGasLimit, requiredGasLimit): boolean {
return bn(setGasLimit).gte(bn(requiredGasLimit));
} Try / catch
import { FuelError, ErrorCode } from '@fuel-ts/errors';
try {
await account.assembleTx({ transactionRequest, setGasLimit });
} catch (e) {
if (e instanceof FuelError && e.code === ErrorCode.GAS_LIMIT_TOO_LOW) {
// drop setGasLimit to let the SDK estimate, or bump it
}
throw e;
} Prevention
- Omit setGasLimit unless you have a fresh estimate.
- Re-estimate gas after any script change.
- Add a 10–20% margin when setting gas manually.
When it happens
Trigger: Calling an assemble/send flow with setGasLimit set to a value below the estimated required gas for a Script transaction; passing a hardcoded low gas limit; computing gas conservatively before estimation updated the request.
Common situations: Migrating from an SDK version that did not validate gas; copying a gas value from a testnet that underestimates mainnet script complexity; setting gas based on the script body without accounting for data inputs; pre-setting gas to avoid overpay but going below the floor.
Related errors
AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12).
Data as JSON: /api/errors/ebd1c3c914d82162.
Report an issue: GitHub.