microsoft/aspire · error · DistributedApplicationException

ConnectionStringAvailableEvent was published for the

Error message

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

What it means

When a Valkey resource's connection string becomes available, Aspire publishes ConnectionStringAvailableEvent and the handler resolves the resource's ConnectionStringExpression. If the resolved value is null, AddValkey throws this DistributedApplicationException because downstream code (health checks, client integrations) cannot function without a connection string.

Solutions

  1. Ensure the Valkey resource has its primary endpoint (don't remove/override WithEndpoint for the 6379 endpoint).
  2. Check that no custom code clears or replaces the resource's ConnectionStringExpression.
  3. If subclassing, verify the constructor passes a non-null connection-string expression (e.g. built from the primary endpoint reference).
  4. Reproduce with minimal AddValkey('valkey') call to rule out custom configuration as the cause.

Example fix

// before
var valkey = builder.AddValkey("cache");
valkey.Resource.Endpoints.Clear(); // breaks connection string resolution
// after
var valkey = builder.AddValkey("cache"); // keep default endpoint intact
Defensive patterns

Strategy: validation

Validate before calling

if (valkey.Resource.ConnectionStringExpression is null)
    throw new InvalidOperationException("Valkey resource has no connection string expression");

Try / catch

try { var app = await builder.BuildAsync(); await app.StartAsync(); }
catch (DistributedApplicationException ex) when (ex.Message.Contains("connection string was null"))
{
    // log resource misconfiguration and abort startup
}

Prevention

When it happens

Trigger: Subscribing to ConnectionStringAvailableEvent for a ValkeyResource whose ConnectionStringExpression evaluates to null — typically when the resource has no primary endpoint/reference configured or the expression resolves before the endpoint exists.

Common situations: Misconfigured ValkeyResource (endpoint removed or overridden), custom resource subclassing Valkey without a connection-string expression, running the resource in an unusual mode (e.g. published without endpoints), or event published prematurely in custom eventing code.

Understand the failure class

Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.Valkey/ValkeyBuilderExtensions.cs:136

        ArgumentNullException.ThrowIfNull(builder);
        ArgumentException.ThrowIfNullOrEmpty(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 valkey = new ValkeyResource(name, passwordParameter);

        string? connectionString = null;

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

            if (connectionString is null)
            {
                throw new DistributedApplicationException($"ConnectionStringAvailableEvent was published for the '{valkey.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);

        return builder.AddResource(valkey)
            .WithEndpoint(port: port, targetPort: 6379, name: ValkeyResource.PrimaryEndpointName)
            .WithImage(ValkeyContainerImageTags.Image, ValkeyContainerImageTags.Tag)
            .WithImageRegistry(ValkeyContainerImageTags.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 (valkey.PasswordParameter is { } password)

View on GitHub (pinned to 25830f84bd)