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

  1. 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
  2. Upgrade BenchmarkDotNet so the toolchain mappings include your target moniker
  3. 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

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


AI-assisted analysis of dotnet/BenchmarkDotNet@b515068b61 (2026-08-13). Data as JSON: /api/errors/c432239520a53bcd. Report an issue: GitHub.