FuelLabs/sway · error · anyhow::Error
Configurables section offset not found
Error message
Configurables section offset not found
What it means
get_bytecode_id detects a configurables-bearing binary by checking that instructions 4 and 5 (CONFIGURABLES_OFFSET_INSTR_LO/HI) both decode to fuel_asm::InvalidOpcode — the sentinel half-words encoding the configurables section offset. If they are not both InvalidOpcode, the expected preamble marker is absent and the function errors. The repo's own regression test reproduces this with a .bin produced by an older compiler that did not embed the offset.
Source
Thrown at forc-util/src/bytecode.rs:111
}
// Continue hashing the remaining instructions up to the configurables section offset.
instructions
.take(
configurables_offset / fuel_asm::Instruction::SIZE
- CONFIGURABLES_OFFSET_PREAMBLE,
) // Minus 6 because we already hashed the first six
.for_each(|(_, raw)| {
hasher.update(raw);
});
let hash_result = hasher.finalize();
let bytecode_id = format!("{hash_result:x}");
return Ok(bytecode_id);
}
}
Err(anyhow!("Configurables section offset not found"))
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_get_bytecode_id_happy() {
// These binary files were generated from `examples/configurable_constants` and `examples/counter`
// using `forc build` and `forc build --release` respectively.
let bytecode_id: String =
get_bytecode_id("tests/fixtures/bytecode/debug-counter.bin").expect("bytecode id");
assert_eq!(
bytecode_id,
"e65aa988cae1041b64dc2d85e496eed0e8a1d8105133bd313c17645a1859d53b".to_string()
);
let bytecode_id =View on GitHub (pinned to 47e5e902fa)
Solutions
- Rebuild the bytecode with the current `forc build` so the preamble contains the offset sentinel, then recompute the ID
- Clear build caches (out/, CI artifact caches) so old-compiler binaries are regenerated
- If you must support legacy binaries, hash them with a tool version matching the one that produced them
Example fix
# before (bin built by old compiler) forc contract-id --bytecode-file cached_old_counter.bin # after forc build && forc contract-id --bytecode-file out/debug/counter.bin
Defensive patterns
Strategy: validation
Validate before calling
// Pre-check that the preamble carries the configurables-offset sentinel
// (instructions 4 and 5 must decode to InvalidOpcode), mirroring get_bytecode_id.
fn has_configurables_offset(path: &Path) -> bool {
let mut it = match forc_util::bytecode::parse_bytecode_to_instructions(path) {
Ok(it) => it,
Err(_) => return false,
};
let instrs: Vec<_> = (&mut it).take(6).collect();
instrs.len() == 6
&& matches!(instrs[4].0, Err(_))
&& matches!(instrs[5].0, Err(_))
} Try / catch
match get_bytecode_id(&path) {
Ok(id) => Ok(id),
Err(e) if e.to_string() == "Configurables section offset not found" => {
Err(anyhow::anyhow!("{} was built by an older compiler; rebuild with current forc", path.display()))
}
Err(e) => Err(e),
} Prevention
- Regenerate .bin artifacts with the current forc after every toolchain upgrade before computing IDs
- Don't cache build artifacts across toolchain versions in CI
When it happens
Trigger: Hashing bytecode compiled by an old sway/forc version that predates the configurables-offset preamble, or hand-modified/malformed bytecode where the sentinel was clobbered.
Common situations: Computing contract IDs for artifacts built before a forc upgrade, CI caches holding stale .bin files across toolchain bumps, or checking in binaries built by mismatched toolchain versions.
Related errors
- {}: file not found
- Incomplete bytecode
- Serialized receipts does not contain {} th index
- only Fuel VM is supported for log decoding
- log id is missing
AI-assisted analysis of FuelLabs/sway@47e5e902fa (2026-08-16).
Data as JSON: /api/errors/f170995a9de91b47.
Report an issue: GitHub.