microsoft/aspire · critical · DistributedApplicationException

ConnectionStringAvailableEvent was published for the

Error message

ConnectionStringAvailableEvent was published for the '{nats.Name}' resource but the connection string was null.

What it means

AddNats subscribes to ConnectionStringAvailableEvent for the NATS resource and evaluates the resource's ConnectionStringExpression when it fires. If the expression evaluates to null, this DistributedApplicationException is thrown, because the event contract guarantees a connection string should exist by that point. It is an internal invariant failure: the resource was announced as ready for connection but produced no value.

Solutions

  1. Ensure the NATS resource's connection string inputs (host/endpoint/parameters) are configured in appsettings.json or Parameters before running the AppHost.
  2. If using a custom NATS resource or WithConnectionString override, verify the expression never returns null and throws a clearer error earlier.
  3. Check that ConnectionStringAvailableEvent is not being published manually or prematurely for this resource.

Example fix

// before
var nats = builder.AddNats("nats");
// after — ensure required parameter exists
var host = builder.AddParameter("nats-host");
var nats = builder.AddNats("nats");
Defensive patterns

Strategy: validation

Validate before calling

// Ensure NATS inputs exist before running
if (builder.Configuration["Parameters:nats-host"] is null &&
    Environment.GetEnvironmentVariable("NATS_HOST") is null)
{
    throw new InvalidOperationException("NATS host configuration missing; connection string will resolve to null.");
}

Try / catch

try { await nats.ConnectionStringExpression.GetValueAsync(ct); } catch (DistributedApplicationException ex) { logger.LogError(ex, "NATS connection string invariant broken"); throw; }

Prevention

When it happens

Trigger: A ConnectionStringAvailableEvent is published for the NatsConnection resource but nats.ConnectionStringExpression.GetValueAsync returns null — e.g. the underlying parameter or endpoint reference backing the connection string is unconfigured or misconfigured when AddNats sets up its client callback.

Common situations: Missing or misnamed configuration/parameter that the NATS connection string expression depends on; custom builds of the resource that removed the endpoint or host reference; running the AppHost in a context where required inputs were not supplied before the event fired.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.Nats/NatsBuilderExtensions.cs:67

    /// <remarks>This overload is not available in polyglot app hosts. Use <see cref="AddNatsForPolyglot"/> instead.</remarks>
    [AspireExportIgnore(Reason = "Use the dedicated polyglot overload instead.")]
    public static IResourceBuilder<NatsServerResource> AddNats(this IDistributedApplicationBuilder builder, [ResourceName] string name, int? port = null,
        IResourceBuilder<ParameterResource>? userName = null,
        IResourceBuilder<ParameterResource>? password = null)
    {
        ArgumentNullException.ThrowIfNull(builder);
        ArgumentException.ThrowIfNullOrEmpty(name);

        var passwordParameter = password?.Resource ?? ParameterResourceBuilderExtensions.CreateDefaultPasswordParameter(builder, $"{name}-password", special: false);

        var nats = new NatsServerResource(name, userName?.Resource, passwordParameter);

        NatsConnection? natsConnection = null;

        builder.Eventing.Subscribe<ConnectionStringAvailableEvent>(nats, async (@event, ct) =>
        {
            var connectionString = await nats.ConnectionStringExpression.GetValueAsync(ct).ConfigureAwait(false)
            ?? throw new DistributedApplicationException($"ConnectionStringAvailableEvent was published for the '{nats.Name}' resource but the connection string was null.");

            var options = NatsOpts.Default with
            {
                LoggerFactory = @event.Services.GetRequiredService<ILoggerFactory>(),
            };

            options = options with
            {
                Url = connectionString,
                AuthOpts = new()
                {
                    Username = await nats.UserNameReference.GetValueAsync(ct).ConfigureAwait(false),
                    Password = await nats.PasswordParameter!.GetValueAsync(ct).ConfigureAwait(false),
                }
            };

            natsConnection = new NatsConnection(options);
        });

View on GitHub (pinned to 25830f84bd)