FuelLabs/fuels-ts · error · FuelError
MAX_FEE_TOO_LOW
MAX_FEE_TOO_LOW
Error message
Max fee '${setMaxFee}' is lower than the required: '${maxFee}'. What it means
Thrown while finalizing a funded transaction when an explicit maxFee was supplied (txParameters.maxFee) but it is below the maxFee the SDK computed as required for the transaction. Like gasLimit, when maxFee is omitted the SDK sets it automatically; when supplied and too low, it errors rather than silently clamping.
Source
Thrown at packages/program/src/functions/base-invocation-scope.ts:675
) {
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 maxFee and let the SDK derive it from gasLimit, gas price, and byte size.
- If you must set it, raise txParameters.maxFee to >= the value shown in the error (with a margin).
- Verify the provider's current gas price (await provider.getGasConfig()) before computing a maxFee.
Example fix
// before
await contract.functions.fn().tx({ maxFee: 100 }).call();
// after
await contract.functions.fn().call();
// or explicit adequate value
await contract.functions.fn().tx({ maxFee: 100_000_000 }).call(); Defensive patterns
Strategy: validation
Validate before calling
// Let the SDK compute maxFee; only set it after reading the gas config. // const gasConfig = await provider.getGasConfig(); // then, if needed, set maxFee >= computed required maxFee.
Try / catch
try {
await contract.functions.fn().tx({ maxFee }).call();
} catch (e) {
if (e instanceof FuelError && e.code === ErrorCode.MAX_FEE_TOO_LOW) {
await contract.functions.fn().call(); // let SDK derive maxFee
} else throw e;
} Prevention
- Avoid hard-coded maxFee; the SDK derives it from gasLimit, price, and byte size.
- Account for gas-price differences between networks before pinning maxFee.
- Re-check maxFee whenever you raise gasLimit or add inputs.
When it happens
Trigger: Calling .tx({ maxFee: N }) with N below the required max fee; setting maxFee from a hard-coded constant that predates a gas-price or byte-size change.
Common situations: Hard-coding maxFee to a small constant; raising gasLimit/inputs (which raises required fee) without updating maxFee; mainnet vs testnet gas-price differences.
Related errors
- GAS_LIMIT_TOO_LOW
- MAX_FEE_TOO_LOW
- INVALID_TRANSACTION_INPUT
- INVALID_TRANSACTION_INPUT
- Witness at index "${index}" was not found
AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12).
Data as JSON: /api/errors/93bc4a0696dc6091.
Report an issue: GitHub.