microsoft/aspire · error · InvalidOperationException
Connection string is unavailable
Error message
Connection string is unavailable
What it means
AddValkey registers a Redis health check whose factory lazily reads the captured connectionString variable. If the health check runs before the ConnectionStringAvailableEvent handler populated it, the factory throws this InvalidOperationException instead of silently failing health checks.
Solutions
- Ensure the Valkey resource starts successfully; check dashboard/logs for resource startup errors so the connection string event fires.
- Wait for the resource to reach Running state (or use WaitFor on dependents) before invoking health checks.
- In tests, await app.ResourceNotifications.WaitForResourceHealthyAsync("cache") before probing health endpoints.
- If the error persists, verify no custom code is suppressing the ConnectionStringAvailableEvent subscription.
Example fix
// before (test)
var response = await client.GetAsync("/health");
// after
await app.ResourceNotifications.WaitForResourceHealthyAsync("cache");
var response = await client.GetAsync("/health"); Defensive patterns
Strategy: retry
Validate before calling
await app.ResourceNotifications.WaitForResourceHealthyAsync("cache"); // before hitting health endpoints Try / catch
try { var rsp = await client.GetAsync("/health"); rsp.EnsureSuccessStatusCode(); }
catch (InvalidOperationException ex) when (ex.Message == "Connection string is unavailable")
{
// resource not started yet; wait and retry
} Prevention
- Wait for resources to become healthy before probing health endpoints.
- Check the dashboard for resource startup failures.
- Use WaitFor in dependents to order startup.
When it happens
Trigger: Health check executes (e.g. during app start or a /health request) while connectionString is still null — the ConnectionStringAvailableEvent either never fired or fired after the health check was invoked.
Common situations: Health checks polled very early at startup; the Valkey resource failed to start so the event never fired; tests hitting the health endpoint before resources are started; resource in error state blocking connection string availability.
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
- Connection string is unavailable
- Connection string is unavailable
- Connection string is unavailable
- Connection string is unavailable
- ConnectionStringAvailableEvent was published for the
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/14cf9d0083a6469f.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Valkey/ValkeyBuilderExtensions.cs:142
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)
{
context.EnvironmentVariables["VALKEY_PASSWORD"] = password;
}
})
.WithArgs(context =>
{View on GitHub (pinned to 25830f84bd)