microsoft/FASTER · error · FasterException
Unable to affinitize thread
Error message
Unable to affinitize thread
What it means
FasterException thrown by Native32.AffinitizeThreadRoundRobin when the Win32 SetThreadGroupAffinity call returns 0 (failure). The library uses this during epoch/thread affinitization to pin threads across processor groups; if the OS refuses the affinity mask, the setup fails fast.
Solutions
- Run on hardware/VM where the thread count does not exceed available logical processors per group
- Avoid thread affinitization (do not enable affinity options) in containers or restricted environments
- Verify the process has permission to set thread affinity (not restricted by Job Object policies)
- Confirm processor group layout with GetActiveProcessorGroupCount/GetActiveProcessorCount and align threadIdx
Example fix
// before
for (int i = 0; i < 128; i++)
Native32.AffinitizeThreadRoundRobin((uint)i, threadHandles[i]);
// after
int procs = Environment.ProcessorCount;
for (int i = 0; i < Math.Min(128, procs); i++)
Native32.AffinitizeThreadRoundRobin((uint)i, threadHandles[i]); Defensive patterns
Strategy: try-catch
Validate before calling
if (OperatingSystem.IsWindows() && threadIdx < Environment.ProcessorCount && CanSetThreadAffinity()) { ... } Try / catch
try { Native32.AffinitizeThreadRoundRobin(idx, thread); }
catch (FasterException ex) when (ex.Message == "Unable to affinitize thread")
{ logger.Warn("Affinity not permitted; continuing without pinning"); } Prevention
- Do not enable thread affinitization in containers, job-restricted or shared VMs
- Keep thread count <= Environment.ProcessorCount
- Only use affinity options on Windows with known processor-group layout
When it happens
Trigger: Calling AffinitizeThreadRoundRobin (used by FasterLog/FASTER server or TickAffinitize setup) on Windows when the requested threadIdx maps to a group/mask the OS rejects — e.g. mask 1 << (threadIdx % procsPerGroup) exceeding available processors in the group, or insufficient privileges (restricted job objects, containers, VMs with limited CPU groups).
Common situations: Running in Windows containers or constrained VMs where thread affinity is not permitted; launching more threads than logical processors; running on systems with multiple processor groups where group math mismatches; using non-Windows where this P/Invoke path is unsupported.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
Related errors
- Async operations not supported over protected epoch
- Cannot use LocalStorageDevice from non-Windows OS platform…
- Error binding log handle for
- Error creating log file for
- Error reading from log file
AI-assisted analysis of microsoft/FASTER@321d872eab (2026-09-15).
Data as JSON: /api/errors/f48b120e9198b0ec.
Report an issue: GitHub.
Appendix: source
Thrown at cs/src/core/Utilities/Native32.cs:238
{
uint nrOfProcessors = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
ushort nrOfProcessorGroups = GetActiveProcessorGroupCount();
uint nrOfProcsPerGroup = nrOfProcessors / nrOfProcessorGroups;
GROUP_AFFINITY groupAffinityThread = default(GROUP_AFFINITY);
GROUP_AFFINITY oldAffinityThread = default(GROUP_AFFINITY);
IntPtr thread = GetCurrentThread();
GetThreadGroupAffinity(thread, ref groupAffinityThread);
threadIdx = threadIdx % nrOfProcessors;
groupAffinityThread.Mask = (ulong)1L << ((int)(threadIdx % (int)nrOfProcsPerGroup));
groupAffinityThread.Group = (uint)(threadIdx / nrOfProcsPerGroup);
if (SetThreadGroupAffinity(thread, ref groupAffinityThread, ref oldAffinityThread) == 0)
{
throw new FasterException("Unable to affinitize thread");
}
}
/// <summary>
/// Get number of groups (sockets) and processors per group
/// </summary>
/// <returns></returns>
public static (uint numGroups, uint numProcsPerGroup) GetNumGroupsProcsPerGroup()
{
uint nrOfProcessors = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
ushort nrOfProcessorGroups = GetActiveProcessorGroupCount();
uint nrOfProcsPerGroup = nrOfProcessors / nrOfProcessorGroups;
return (nrOfProcessorGroups, nrOfProcsPerGroup);
}
/// <summary>
/// Accepts thread id = 0, 1, 2, ... and sprays them round-robin
/// across all cores (viewed as a flat space). On NUMA machines,View on GitHub (pinned to 321d872eab)