FuelLabs/fuels-ts · error · FuelError
GAS_LIMIT_TOO_LOW
GAS_LIMIT_TOO_LOW
Error message
Gas limit '${setGasLimit}' is lower than the required: '${gasUsed}'. What it means
Thrown while finalizing a funded transaction when an explicit gas limit was supplied (via txParameters.gasLimit or callParams.gasLimit) but it is below the gas the SDK actually estimated as required (gasUsed). The SDK will not silently raise your cap; it treats an under-set gas limit as a caller error. When no gas limit is specified, the SDK simply sets transactionRequest.gasLimit = gasUsed.
Source
Thrown at packages/program/src/functions/base-invocation-scope.ts:666
}
/**
* In case the gasLimit is *not* set by the user, this method sets a default value.
*/
private setDefaultTxParams(
transactionRequest: ScriptTransactionRequest,
gasUsed: BN,
maxFee: BN
) {
const gasLimitSpecified = isDefined(this.txParameters?.gasLimit) || this.hasCallParamsGasLimit;
const maxFeeSpecified = isDefined(this.txParameters?.maxFee);
const { gasLimit: setGasLimit, maxFee: setMaxFee } = transactionRequest;
if (!gasLimitSpecified) {
transactionRequest.gasLimit = gasUsed;
} else if (setGasLimit.lt(gasUsed)) {
throw new FuelError(
ErrorCode.GAS_LIMIT_TOO_LOW,
`Gas limit '${setGasLimit}' is lower than the required: '${gasUsed}'.`
);
}
if (!maxFeeSpecified) {
transactionRequest.maxFee = maxFee;
} else if (maxFee.gt(setMaxFee)) {
throw new FuelError(
ErrorCode.MAX_FEE_TOO_LOW,
`Max fee '${setMaxFee}' is lower than the required: '${maxFee}'.`
);
}
}
}
View on GitHub (pinned to b3f37c91ac)
Solutions
- Omit gasLimit entirely and let the SDK estimate it from gasUsed.
- Estimate first (await scope.txParams({}).getTransactionRequest() / dryRun) and set gasLimit to a value >= gasUsed (add a margin).
- Raise the explicit gasLimit to at least the value reported in the error message.
Example fix
// before
await contract.functions.heavy().tx({ gasLimit: 1000 }).call();
// after — let the SDK estimate
await contract.functions.heavy().call();
// or set an adequate limit
await contract.functions.heavy().tx({ gasLimit: 1_000_000 }).call(); Defensive patterns
Strategy: validation
Validate before calling
// Omit gasLimit unless you have a confident estimate >= gasUsed.
// Optionally estimate first:
const prepared = await contract.functions.fn().txParams({}).getTransactionRequest();
// `prepared` exposes computed gas; set gasLimit only if it exceeds that. Try / catch
try {
await contract.functions.fn().tx({ gasLimit }).call();
} catch (e) {
if (e instanceof FuelError && e.code === ErrorCode.GAS_LIMIT_TOO_LOW) {
// retry without an explicit gasLimit to let the SDK estimate
await contract.functions.fn().call();
} else throw e;
} Prevention
- Do not hard-code gasLimit; omit it or compute it with a margin over the estimate.
- When migrating contract builds, re-estimate gas rather than reusing old constants.
- Watch for gas changes when adding logic or inputs to a function.
When it happens
Trigger: Calling .tx({ gasLimit: N }) or .callParams({ gasLimit: N }) with N smaller than the estimated gas; computing gasLimit from stale constants; reusing a gasLimit tuned for a cheaper function on a heavier one.
Common situations: Hard-coding a gasLimit from an older contract build after adding logic that needs more gas; setting gasLimit to a 'safe-looking' small number; mixing gasLimit on both .tx() and .callParams() and under-shooting.
Related errors
AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12).
Data as JSON: /api/errors/4588a45005f50869.
Report an issue: GitHub.