microsoft/FASTER · error · FasterException
Physical pointer returned by allocator: de-reference…
Error message
Physical pointer returned by allocator: de-reference pointer to set records instead of calling Set (otherwise, set ForceUnpinnedAllocation to true)
What it means
Same family as Get: when MallocFixedPageSize is in physical-address mode (ReturnPhysicalAddress), Set(long index, ref T value) is disabled because writes must go through the raw pointer, and record pinning is managed by the heap container. Calling Set throws FasterException; either dereference the physical address to write, or configure ForceUnpinnedAllocation if pinned physical pointers are not used.
Solutions
- Write via the physical pointer: *(T*)allocator.GetPhysicalAddress(index) = value; (or Unsafe.As/ref dereference)
- Set ForceUnpinnedAllocation = true in the allocator configuration if unpinning is intended and Set should be allowed
- Reconfigure the allocator with ReturnPhysicalAddress = false when Set/Get object access is required
- Update shared write helpers to branch on allocator mode like read helpers
Example fix
// before
allocator.Set(index, ref newValue);
// after
if (allocator.ReturnPhysicalAddress)
{
*(T*)allocator.GetPhysicalAddress(index) = newValue;
}
else
{
allocator.Set(index, ref newValue);
} Defensive patterns
Strategy: type-guard
Validate before calling
// Check allocator mode before writing
if (allocator.ReturnPhysicalAddress)
*(T*)allocator.GetPhysicalAddress(index) = value;
else
allocator.Set(index, ref value); Type guard
static bool RequiresPointerWrite(MallocFixedPageSize<T> a) => a.ReturnPhysicalAddress;
Try / catch
try
{
allocator.Set(index, ref value);
}
catch (FasterException ex) when (ex.Message.Contains("Physical pointer returned by allocator"))
{
*(T*)allocator.GetPhysicalAddress(index) = value;
} Prevention
- In physical-address mode, always write through GetPhysicalAddress dereference
- If Set is required, configure ForceUnpinnedAllocation=true at allocator construction
- Mirror the read-side branching in all write helpers
- Use IHeapContainer consistently when the allocator is in physical-address mode
When it happens
Trigger: Calling allocator.Set(index, ref value) on a ReturnPhysicalAddress = true MallocFixedPageSize; seen in tests/code like BasicIHeapContainerMallocFPSTest paths that write through IHeapContainer against physical-address allocators.
Common situations: Reusing Set()-based write helpers after enabling physical-address mode; writing to allocator slots directly in custom heap containers or recovery code without dereferencing pointers.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Physical pointer returned by allocator: de-reference…
- Size of key-value exceeds max of 2GB:
- Incremental snapshots not supported with generic allocator
- LockableUnsafeContext requires
- LockableContext requires
AI-assisted analysis of microsoft/FASTER@321d872eab (2026-09-15).
Data as JSON: /api/errors/c6b90c82413160d7.
Report an issue: GitHub.
Appendix: source
Thrown at cs/src/core/Allocator/MallocFixedPageSize.cs:188
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref T Get(long index)
{
if (ReturnPhysicalAddress)
throw new FasterException("Physical pointer returned by allocator: de-reference pointer to get records instead of calling Get");
Debug.Assert(index != kInvalidAllocationIndex, "Invalid allocation index");
return ref values[index >> PageSizeBits][index & PageSizeMask];
}
/// <summary>
/// Set object
/// </summary>
/// <param name="index"></param>
/// <param name="value"></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Set(long index, ref T value)
{
if (ReturnPhysicalAddress)
throw new FasterException("Physical pointer returned by allocator: de-reference pointer to set records instead of calling Set (otherwise, set ForceUnpinnedAllocation to true)");
Debug.Assert(index != kInvalidAllocationIndex, "Invalid allocation index");
values[index >> PageSizeBits][index & PageSizeMask] = value;
}
/// <summary>
/// Free object
/// </summary>
/// <param name="pointer"></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Free(long pointer)
{
if (!ReturnPhysicalAddress)
values[pointer >> PageSizeBits][pointer & PageSizeMask] = default;
freeList.Enqueue(pointer);
}
internal int FreeListCount => freeList.Count; // For test
View on GitHub (pinned to 321d872eab)