microsoft/aspire · error
Histogram data point bucket count length changed.
Error message
Histogram data point bucket count length changed.
What it means
The repository models histograms as deltas keyed by fixed bucket layouts. When a new histogram point arrives whose bucket count array length differs from the previously stored point for the same dimension, the bucket boundaries changed mid-stream, so AddHistogramMetricPoint throws rather than producing inconsistent series.
Solutions
- Restart the emitting app after changing histogram bucket boundaries, or keep boundaries stable for the process lifetime.
- Clear/reset dashboard telemetry state (or restart the dashboard) so the old bucket layout is discarded.
- Keep explicit bucket boundaries consistent across deployments of the same service.
- If using SDK auto bucket advice, pin explicit boundaries to avoid layout changes across SDK versions.
Example fix
// before: boundaries changed at runtime
var hist = meter.CreateHistogram<double>("latency");
// SDK advice changes after config reload -> bucket count changes
// after: pin explicit boundaries and restart the app
var hist = meter.CreateHistogram<double>("latency",
advice: new InstrumentAdvice<double> { HistogramBucketBoundaries = new[] { 0d, 10, 50, 100, 500, 1000 } }); Defensive patterns
Strategy: try-catch
Validate before calling
if (lastBucketCounts is { } prev && prev.Length != point.BucketCounts.Count)
{
// bucket layout changed; reset resource state before sending
} Try / catch
try
{
await repo.AddMetricsAsync(request);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("bucket count length changed"))
{
logger.LogWarning(ex, "Histogram bucket layout changed; restarting emitter is required.");
} Prevention
- Pin histogram bucket boundaries via InstrumentAdvice.HistogramBucketBoundaries.
- Restart the app whenever SDK/bucket configuration changes.
- Keep bucket boundaries consistent across deployments of the same resource.
When it happens
Trigger: AddMetricToDatabase -> AddHistogramMetricPoint sees latestPointType == HistogramPointType and the stored latestBucketCountLength differs from point.BucketCounts.Count.
Common situations: The emitting app changed its histogram bucket boundaries (advice or explicit boundaries) while running; switching instrumentation libraries or SDK config without restarting the app; a rebuilt service reusing the same resource identity with a new bucket layout, sending to a dashboard with retained state.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Dimension limit of reached.
- Histogram data point bucket count length changed.
- Histogram data point has bucket counts without any explicit…
- Histogram data point sum must be finite.
- Instrument limit of reached. Instrument ' ' will not be…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/b2c7fa733cc130e2.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Dashboard/Otlp/Storage/SqliteTelemetryRepository.Metrics.Writes.cs:262
IDbTransaction transaction,
AddContext context,
long instrumentId,
HistogramDataPoint point,
MetricIngestionState ingestionState,
MetricPointBatch pointBatch)
{
try
{
OtlpHelpers.ValidateHistogramDataPoint(point);
var dimension = GetOrAddMetricDimension(connection, transaction, instrumentId, point.Attributes, ingestionState);
var pendingLatest = dimension.PendingPoint;
var latest = dimension.LatestPoint;
var latestPointType = pendingLatest?.PointType ?? latest?.PointType;
var latestEndTimeTicks = pendingLatest?.EndTimeTicks ?? latest?.EndTimeTicks;
var latestBucketCountLength = pendingLatest?.HistogramBucketCounts?.Length ?? latest?.HistogramBucketCountLength;
if (latestPointType == HistogramPointType && latestBucketCountLength != point.BucketCounts.Count)
{
throw new InvalidOperationException("Histogram data point bucket count length changed.");
}
var histogramCount = checked((long)point.Count);
var sameCount = latestPointType == HistogramPointType &&
(pendingLatest?.HistogramCount ?? latest?.HistogramCount) == histogramCount;
var endTimeTicks = OtlpHelpers.UnixNanoSecondsToDateTime(point.TimeUnixNano).Ticks;
if (sameCount)
{
if (pendingLatest is not null)
{
pendingLatest.EndTimeTicks = endTimeTicks;
pendingLatest.SourcePointCount++;
pendingLatest.Exemplars.AddRange(point.Exemplars);
}
else
{
pointBatch.AddUpdate(latest!.PointId, endTimeTicks, incrementRepeatCount: false);
latest.EndTimeTicks = endTimeTicks;
QueueMetricExemplars(pointBatch, latest.PointId, point.Exemplars);View on GitHub (pinned to 25830f84bd)