microsoft/aspire · error

Scope limit of reached. Scope ' ' will not be added.

Error message

Scope limit of {TelemetryRepositoryLimits.MaxScopeCount} reached. Scope '{incomingScope.Name}' will not be added.

What it means

The SQLite telemetry repository caps the total number of instrumentation scopes stored in telemetry_scopes at TelemetryRepositoryLimits.MaxScopeCount. GetOrAddCachedScope throws this InvalidOperationException when inserting a new scope would exceed the limit; the scope is not added and its telemetry is dropped. This mirrors the in-memory scope limit (error 322) on the persistence layer.

Solutions

  1. Fix producers to use a bounded set of stable scope names/versions (static Meter/ActivitySource names).
  2. Aggregate or filter telemetry upstream (collector) so fewer distinct scopes reach the repository.
  3. Identify which exporter/libraries contribute the most scopes and consolidate their instrumentation definitions.

Example fix

// before: dynamic meter name
var meter = new MeterFactory.Create($"Metrics.{tenantId}");
// after: one stable meter, tenant as an attribute
var meter = new MeterFactory.Create("MyApp.Metrics");
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    await repository.AddMetricsToDatabaseAsync(batch);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Scope limit of"))
{
    logger.LogWarning(ex, "Scope limit reached; scope '{Name}' dropped.", incomingScope.Name);
}

Prevention

When it happens

Trigger: GetOrAddCachedScope throws when SELECT COUNT(*) FROM telemetry_scopes >= MaxScopeCount and a scope not already in the cache (by name/version) is added, reached via cachedScope or AddMetricsToDatabaseAsync. Triggered on metric ingestion when telemetry carries more distinct InstrumentationScope identities than the limit.

Common situations: Applications creating Meters with dynamic names (per-request, per-tenant); many libraries each shipping their own instrumentation scope converging on one Dashboard; long-lived sessions where new scope versions accumulate after deployments; third-party instrumentation generating unique scope versions per release.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/d7b1779dbf5625dc. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Dashboard/Otlp/Storage/SqliteTelemetryRepository.Caching.cs:228

                    FROM telemetry_scopes s
                    LEFT JOIN telemetry_scope_attributes a ON a.scope_id = s.scope_id
                    WHERE s.scope_name = @ScopeName
                    ORDER BY a.ordinal;
                    """, new { ScopeName = incomingScope.Name }, transaction);
                if (existingRecords.FirstOrDefault() is { } existing)
                {
                    var attributes = existingRecords
                        .Where(record => record.AttributeKey is not null)
                        .Select(record => KeyValuePair.Create(record.AttributeKey!, record.AttributeValue!))
                        .ToArray();
                    cachedScope = GetOrAddCachedScope(existing.ScopeId, existing.ScopeName, existing.ScopeVersion, attributes);
                }
                else
                {
                    var scopeCount = connection.QuerySingle<int>("SELECT COUNT(*) FROM telemetry_scopes;", transaction: transaction);
                    if (scopeCount >= TelemetryRepositoryLimits.MaxScopeCount)
                    {
                        throw new InvalidOperationException($"Scope limit of {TelemetryRepositoryLimits.MaxScopeCount} reached. Scope '{incomingScope.Name}' will not be added.");
                    }

                    var scopeId = connection.QuerySingle<long>("""
                        INSERT INTO telemetry_scopes (scope_name, scope_version)
                        VALUES (@ScopeName, @ScopeVersion)
                        RETURNING scope_id;
                        """, new { ScopeName = incomingScope.Name, ScopeVersion = incomingScope.Version }, transaction);
                    var attributes = incomingScope.Attributes
                        .Select((attribute, ordinal) => (Ordinal: ordinal, attribute.Key, attribute.Value))
                        .ToArray();
                    SqliteBatchInsert.BatchInsertRows(
                        connection,
                        transaction,
                        attributes,
                        MaxMetadataAttributeBatchSize,
                        "telemetry_scope_attributes",
                        ["scope_id", "ordinal", "attribute_key", "attribute_value"],
                        (attribute, parameters) =>

View on GitHub (pinned to 25830f84bd)