wasmerio/wasmer · error
Internal error: allocated index {allocated_index} does not m
Error message
Internal error: allocated index {allocated_index} does not match expected index {index} What it means
apply_function_table_allocation allocates table space via allocate_function_table and then asserts the returned base index equals the index recorded in the DL operation. A mismatch means the allocator's state no longer matches the serialized/recorded allocation, so all precomputed function pointers would be off. This is an internal consistency check for replaying dynamic-link operations.
Source
Thrown at lib/wasix/src/state/linker/instance_group/table.rs:171
self.place_in_function_table_at(store, func.clone(), function_table_index)
.map_err(LinkError::TableAllocationError)?;
Ok(())
}
pub(super) fn apply_function_table_allocation(
&mut self,
store: &mut impl AsStoreMut,
index: u32,
size: u32,
) -> Result<(), LinkError> {
trace!(index, "Applying function table allocation");
let allocated_index = self
.allocate_function_table(store, size, 0)
.map_err(LinkError::TableAllocationError)? as u32;
if allocated_index != index {
panic!(
"Internal error: allocated index {allocated_index} does not match expected index {index}"
);
}
Ok(())
}
}
View on GitHub (pinned to 8c4b9ee9d3)
Solutions
- Apply DL operations in the exact order they were recorded, into a fresh instance group
- Do not interleave manual allocate_function_table calls with replayed allocations
- Re-record the operation log from the current run instead of reusing a stale one
- Verify only one code path mutates the function table per group
Example fix
// before: stale op applied to a mutated table
for op in recorded_ops { group.apply_dl_operation(store, &state, op)?; }
// after: replay into a fresh group created for this run
let group = InstanceGroup::new();
for op in recorded_ops { group.apply_dl_operation(store, &state, op)?; } Defensive patterns
Strategy: validation
Validate before calling
fn replay(ops: Vec<DlOperation>) {
assert!(!ops_replayed, "replay each op log exactly once, into a fresh group");
ops_replayed = true;
// apply ops in recorded order with no interleaved manual allocations
} Type guard
fn is_contiguous_allocation(prev_index: u64, size: u64, next: u64) -> bool {
next == prev_index + size
} Prevention
- Replay DL operations in recorded order into a fresh group
- Never interleave manual allocate_function_table calls with replays
- Re-record op logs after any linker version or module change
- Keep a single writer to the function table per group
When it happens
Trigger: apply_dl_operation replaying an allocation whose recorded index differs from the allocator's current position; interleaved table allocations between recording and applying; applying operations out of order or applying an old operation log to a reused group.
Common situations: Replaying a DL operation log into a group that already made other allocations; concurrent/interleaved dlopen flows mutating the table between record and apply; state snapshots mixed across groups.
Related errors
- Internal error: resolution record for symbol {name} indicate
- Internal error: function table index {index} already occupie
- Internal error: table base out of sync with linker state
- Internal error: module {resolved_from:?} not loaded by this
- Internal error: unexpected symbol resolution {r:?} for reque
AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01).
Data as JSON: /api/errors/a13d248d1ed9bda1.
Report an issue: GitHub.