dotnet/BenchmarkDotNet · error · InvalidOperationException
One overhead iteration stop event is missing, unable to calc
Error message
One overhead iteration stop event is missing, unable to calculate stats
What it means
CalculateMetrics requires overhead (jitting/allocations floor) iterations to come in start/stop pairs. It throws when overheadTimestamps.Count is odd, meaning an OverheadActualStart was seen without its matching OverheadActualStop, so an iteration boundary cannot be reconstructed.
Source
Thrown at src/BenchmarkDotNet.Diagnostics.Windows/Tracing/TraceLogParser.cs:124
}
else if (iterationMode == IterationMode.Workload)
{
if (!totalOperationsPerIteration.HasValue)
totalOperationsPerIteration = totalOperations;
else if (totalOperationsPerIteration.Value != totalOperations)
throw new InvalidOperationException($"TotalOperations count can't change during the benchmark run! Invalid trace!");
workloadTimestamps.Add(timeStamp);
}
}
public void HandleNewSample(double timeStamp, ulong instructionPointer, int profileSourceId)
=> samples.Add((timeStamp, instructionPointer, profileSourceId));
public IEnumerable<Metric> CalculateMetrics(Dictionary<int, int> profileSourceIdToInterval, PreciseMachineCounter[] counters)
{
if (overheadTimestamps.Count % 2 != 0)
throw new InvalidOperationException("One overhead iteration stop event is missing, unable to calculate stats");
if (workloadTimestamps.Count % 2 != 0)
throw new InvalidOperationException("One workload iteration stop event is missing, unable to calculate stats");
if (!totalOperationsPerIteration.HasValue)
throw new InvalidOperationException("TotalOperations is missing, unable to calculate stats");
var overheadIterations = CreateIterationData(overheadTimestamps);
var workloadIterations = CreateIterationData(workloadTimestamps);
SumCountersPerIterations(profileSourceIdToInterval, workloadIterations, overheadIterations, counters);
var workloadTotalPerCounter = Sum(workloadIterations);
var overheadTotalPerCounter = Sum(overheadIterations);
return workloadTotalPerCounter.Select(perCounter =>
{
var pmc = counters.Single(counter => counter.ProfileSourceId == perCounter.Key);
overheadTotalPerCounter.TryGetValue(perCounter.Key, out var overhead);View on GitHub (pinned to b515068b61)
Solutions
- Increase ETW session buffer sizes / use a real-time session with larger buffers to avoid dropped events.
- Ensure the benchmark run completes without exceptions so all Start/Stop pairs are emitted.
- Re-run the benchmark; transient event loss often does not recur.
Defensive patterns
Strategy: retry
Try / catch
try { /* run + parse trace */ }
catch (InvalidOperationException ex) when (ex.Message.Contains("overhead iteration stop event is missing"))
{
log.Warning("ETW dropped an overhead stop event; increasing buffers and rerunning.");
// increase ETW buffer sizes and rerun
} Prevention
- Use sufficiently large ETW session buffers to avoid dropped events.
- Ensure the benchmark run completes without exceptions so all Start/Stop pairs fire.
- Capture the .etl over the full run window.
When it happens
Trigger: The ETW trace is missing an OverheadActualStop (or Start) event. Caused by event loss in the ETW session, the benchmarked process crashing/exiting mid-iteration, or the trace being captured over only part of the run.
Common situations: Capturing an .etl with insufficient buffer size (events dropped); the process under test was killed; trace started after the first overhead iteration or stopped before the last; running the PMC diagnoser on a benchmark that threw an exception partway through.
Related errors
- One workload iteration stop event is missing, unable to calc
- TotalOperations is missing, unable to calculate stats
- Sampling interval change is not supported!
- TotalOperations count can't change during the benchmark run!
- Please use Targets property
AI-assisted analysis of dotnet/BenchmarkDotNet@b515068b61 (2026-08-13).
Data as JSON: /api/errors/76c6c5db5b2a9046.
Report an issue: GitHub.