dotnet/BenchmarkDotNet · error · ArgumentOutOfRangeException
RuntimeMoniker not supported
Error message
RuntimeMoniker not supported
What it means
Thrown by the private GetToolchain(RuntimeMoniker) method when a RuntimeMoniker enum value is not covered by its switch statement. This second-level resolver maps known monikers (Net*, NativeAot*, Mono*, R2R*) to concrete toolchains; any uncovered value — most notably RuntimeMoniker.NotRecognized or a moniker enum member added in a newer BDN version but not yet wired up here — hits the default and raises ArgumentOutOfRangeException. Normal callers guard NotRecognized before calling, so in practice this fires on unmapped valid enum values.
Source
Thrown at src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs:223
return MonoToolchain.Mono10_0;
case RuntimeMoniker.Mono11_0:
return MonoToolchain.Mono11_0;
case RuntimeMoniker.R2R80:
return R2RToolchain.R2R80;
case RuntimeMoniker.R2R90:
return R2RToolchain.R2R90;
case RuntimeMoniker.R2R10_0:
return R2RToolchain.R2R10_0;
case RuntimeMoniker.R2R11_0:
return R2RToolchain.R2R11_0;
default:
throw new ArgumentOutOfRangeException(nameof(runtimeMoniker), runtimeMoniker, "RuntimeMoniker not supported");
}
}
}
}
View on GitHub (pinned to b515068b61)
Solutions
- Use a RuntimeMoniker that is explicitly mapped in your BDN version (Net80, Net90, Net10_0, NativeAot80, R2R80, etc.) — check the switch in ToolchainExtensions for your version
- Upgrade BenchmarkDotNet so the toolchain mappings include your target moniker
- Bypass moniker dispatch entirely by setting an explicit toolchain with .WithToolchain(...) on the Job, so neither GetToolchain(Runtime) nor GetToolchain(RuntimeMoniker) is called
Example fix
// before — assumes a moniker BDN's switch does not cover
var job = Job.Default.WithRuntime(CoreRuntime.FromId("net12.0"));
// => if RuntimeMoniker.Net12_0 exists in the enum but has no toolchain case:
// ArgumentOutOfRangeException: RuntimeMoniker not supported
// after (explicit toolchain for an unsupported moniker)
var job = Job.Default
.WithToolchain(CsProjCoreToolchain.From(
new NetCoreAppSettings("net12.0", ".NET 12"))); Defensive patterns
Strategy: validation
Validate before calling
// Verify a RuntimeMoniker is one BDN actually maps to a toolchain before relying on automatic dispatch.
using System.Reflection;
using BenchmarkDotNet.Environments;
static readonly HashSet<RuntimeMoniker> MappedMonikers = new()
{
RuntimeMoniker.Net461, RuntimeMoniker.Net462, RuntimeMoniker.Net47, RuntimeMoniker.Net471,
RuntimeMoniker.Net472, RuntimeMoniker.Net48, RuntimeMoniker.Net481,
RuntimeMoniker.NetCoreApp20, RuntimeMoniker.NetCoreApp21, RuntimeMoniker.NetCoreApp22,
RuntimeMoniker.NetCoreApp30, RuntimeMoniker.NetCoreApp31,
RuntimeMoniker.Net50, RuntimeMoniker.Net60, RuntimeMoniker.Net70, RuntimeMoniker.Net80,
RuntimeMoniker.Net90, RuntimeMoniker.Net10_0, RuntimeMoniker.Net11_0,
RuntimeMoniker.NativeAot70, RuntimeMoniker.NativeAot80, RuntimeMoniker.NativeAot90,
RuntimeMoniker.NativeAot10_0, RuntimeMoniker.NativeAot11_0,
RuntimeMoniker.Mono60, RuntimeMoniker.Mono70, RuntimeMoniker.Mono80,
RuntimeMoniker.Mono90, RuntimeMoniker.Mono10_0, RuntimeMoniker.Mono11_0,
RuntimeMoniker.R2R80, RuntimeMoniker.R2R90, RuntimeMoniker.R2R10_0, RuntimeMoniker.R2R11_0,
};
static void EnsureMappedMoniker(RuntimeMoniker m)
{
if (!MappedMonikers.Contains(m))
throw new ArgumentOutOfRangeException(
nameof(m), $"RuntimeMoniker {m} has no toolchain mapping in this BDN version; set an explicit toolchain.");
} Type guard
// Narrow a RuntimeMoniker to the set that has a concrete toolchain. static bool IsMonikerMapped(RuntimeMoniker m) => m != RuntimeMoniker.NotRecognized && MappedMonikers.Contains(m);
Try / catch
try { BenchmarkRunner.Run<MyBench>(); }
catch (ArgumentOutOfRangeException ex) when (ex.Message.Contains("RuntimeMoniker not supported"))
{
throw new InvalidOperationException(
"The RuntimeMoniker has no toolchain mapping in this BDN version. " +
"Upgrade BDN or set an explicit toolchain via .WithToolchain(...).", ex);
} Prevention
- Set an explicit toolchain with .WithToolchain(...) for any cutting-edge or preview moniker so dispatch never reaches the unmapped default.
- Upgrade BenchmarkDotNet in lockstep with new .NET versions so new RuntimeMoniker members have matching toolchain cases.
- Never pass RuntimeMoniker.NotRecognized into a job expecting automatic toolchain resolution; it is explicitly excluded by all callers.
When it happens
Trigger: The private GetToolchain(RuntimeMoniker) at line 117 is reached from the public GetToolchain(Runtime,...) when a runtime's RuntimeMoniker != NotRecognized (e.g. ClrRuntime line 53, CoreRuntime line 93-94, NativeAotRuntime line 99-100, R2RRuntime line 107-108). If that moniker is a real enum value with no case in the switch (e.g. a future Net12_0 added to the enum but no toolchain mapping, or NotRecognized slipping through), the default at line 222 throws.
Common situations: Using a RuntimeMoniker from a newer BDN enum against an older BDN runtime that lacks the toolchain constant. A version-skew between the Environments assembly (enum) and the Toolchains assembly (switch). Casting an arbitrary integer to RuntimeMoniker producing an undefined member. NotRecognized reaching the call because a caller's guard was bypassed.
Related errors
- Runtime not supported
- Invalid TFM: '{0}'
- Runtime moniker {runtimeMoniker} is not supported
- Runtime moniker {runtimeMoniker} is not supported
- Runtime {runtimeId} is not supported
AI-assisted analysis of dotnet/BenchmarkDotNet@b515068b61 (2026-08-13).
Data as JSON: /api/errors/c432239520a53bcd.
Report an issue: GitHub.