microsoft/aspire · error · DistributedApplicationException

ConnectionStringAvailableEvent was published for the

Error message

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

What it means

When a Redis resource's ConnectionStringAvailableEvent fires, AddRedis retrieves the connection string and expects it to be non-null. If it is still null, an internal invariant of the eventing lifecycle is broken (the event should only publish once the connection string exists), so Aspire throws a DistributedApplicationException immediately rather than propagating a null downstream.

Solutions

  1. Inspect why the Redis resource has no connection string: ensure the primary endpoint annotation is intact and hasn't been removed.
  2. Avoid removing endpoints/annotations from the RedisResource via builder APIs that alter connection string generation.
  3. If using a custom derived resource, ensure GetConnectionStringAsync returns a valid value before the event can publish.
Defensive patterns

Strategy: try-catch

Validate before calling

// Cannot be checked by the caller before the event; ensure the Redis resource is configured with its primary endpoint before running the app host.

Try / catch

try { await distributedApplication.StartAsync(); } catch (DistributedApplicationException ex) when (ex.Message.Contains("ConnectionStringAvailableEvent") && ex.Message.Contains("was null")) { // inspect resource configuration: connection string generation returned null }

Prevention

When it happens

Trigger: Subscribing to ConnectionStringAvailableEvent for a RedisResource where redis.GetConnectionStringAsync(ct) returns null — typically when the resource has no endpoint/reference that yields a connection string at event time.

Common situations: Custom configurations that removed or renamed the primary endpoint, derived resources overriding connection string generation to return null, or hosting scenarios where the event fires before the connection string is set.

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/70efb84a0fb28d08. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Redis/RedisBuilderExtensions.cs:88

        ArgumentNullException.ThrowIfNull(builder);
        ArgumentNullException.ThrowIfNull(name);

        // StackExchange.Redis doesn't support passwords with commas.
        // See https://github.com/StackExchange/StackExchange.Redis/issues/680 and
        // https://github.com/Azure/azure-dev/issues/4848
        var passwordParameter = password?.Resource ?? ParameterResourceBuilderExtensions.CreateDefaultPasswordParameter(builder, $"{name}-password", special: false);

        var redis = new RedisResource(name, passwordParameter);

        string? connectionString = null;

        builder.Eventing.Subscribe<ConnectionStringAvailableEvent>(redis, async (@event, ct) =>
        {
            connectionString = await redis.GetConnectionStringAsync(ct).ConfigureAwait(false);

            if (connectionString == null)
            {
                throw new DistributedApplicationException($"ConnectionStringAvailableEvent was published for the '{redis.Name}' resource but the connection string was null.");
            }
        });

        var healthCheckKey = $"{name}_check";
        builder.Services.AddHealthChecks().AddRedis(sp => connectionString ?? throw new InvalidOperationException("Connection string is unavailable"), name: healthCheckKey);

        var redisBuilder = builder.AddResource(redis)
            .WithEndpoint(port: port, targetPort: 6379, name: RedisResource.PrimaryEndpointName, scheme: RedisResource.StandardRedisScheme)
            .WithImage(RedisContainerImageTags.Image, RedisContainerImageTags.Tag)
            .WithImageRegistry(RedisContainerImageTags.Registry)
            .WithIconName("Database")
            .WithHealthCheck(healthCheckKey)
            // see https://github.com/microsoft/aspire/issues/3838 for why the password is passed this way
            .WithEntrypoint("/bin/sh")
            .WithEnvironment(context =>
            {
                if (redis.PasswordParameter is { } password)
                {

View on GitHub (pinned to 25830f84bd)