dotnet/BenchmarkDotNet · error · NotSupportedException

Unsupported extension on source '{source}', must have the ex

Error message

Unsupported extension on source '{source}', must have the extension '.dll' or '.exe'.

What it means

ValidateSourceIsAssemblyOrThrow throws NotSupportedException when the source has an extension but it is neither '.dll' nor '.exe' (case-insensitive). The adapter can only load managed benchmark assemblies of those two types.

Source

Thrown at src/BenchmarkDotNet.TestAdapter/VSTestAdapter.cs:241

            var appDomain = AppDomain.CreateDomain(domainName, null, setup);
            return appDomain.CreateInstanceAndUnwrap(
                type.Assembly.FullName, type.FullName, false, BindingFlags.Default, null, null, null, null);
#else
            return Activator.CreateInstance(type);
#endif
        }

        private static void ValidateSourceIsAssemblyOrThrow(string source)
        {
            if (string.IsNullOrEmpty(source))
                throw new ArgumentException($"'{nameof(source)}' cannot be null or whitespace.", nameof(source));

            if (!Path.HasExtension(source))
                throw new NotSupportedException($"Missing extension on source '{source}', must have the extension '.dll' or '.exe'.");

            var extension = Path.GetExtension(source);
            if (!string.Equals(extension, ".dll", StringComparison.OrdinalIgnoreCase) && !string.Equals(extension, ".exe", StringComparison.OrdinalIgnoreCase))
                throw new NotSupportedException($"Unsupported extension on source '{source}', must have the extension '.dll' or '.exe'.");
        }
    }
}

View on GitHub (pinned to b515068b61)

Solutions

  1. Pass the assembly file specifically (.dll or .exe), not a sibling artifact.
  2. When enumerating build output, filter for the assembly extension rather than the first matching file.
  3. Fix the path resolution in the calling test platform/tooling.

Example fix

// before
var source = "bin/Debug/net8.0/MyBenchmarks.pdb"; // wrong artifact

// after
var source = "bin/Debug/net8.0/MyBenchmarks.dll";
Defensive patterns

Strategy: validation

Validate before calling

static string RequireAssemblyExtension(string source)
{
    var ext = Path.GetExtension(source);
    if (!ext.Equals(".dll", StringComparison.OrdinalIgnoreCase) &&
        !ext.Equals(".exe", StringComparison.OrdinalIgnoreCase))
        throw new ArgumentException($"source '{source}' must end in .dll/.exe", nameof(source));
    return source;
}

Prevention

When it happens

Trigger: Source is a file with some other extension, e.g. 'MyBenchmarks.exe.config', 'MyBenchmarks.pdb', 'MyBenchmarks.json', or a script/.csproj passed by mistake.

Common situations: Forwarding a build artifact that is not the assembly (.pdb, .config, .json sidecar); pointing at a .csproj instead of the build output; tooling that resolves to a wrong file in the output directory.

Related errors


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