microsoft/aspire · warning · InvalidOperationException

Connection string is unavailable

Error message

Connection string is unavailable

What it means

The Oracle health check registered by AddOracle resolves the captured connection string via a factory: connectionString ?? throw new InvalidOperationException("Connection string is unavailable"). If the health check runs before the ConnectionStringAvailableEvent handler has populated the field, the check fails with this error. It is a timing/state issue between the event subscription and the health check execution.

Solutions

  1. Wait for the resource to become running/healthy rather than querying health status during startup.
  2. If the event never fires, fix the underlying resource startup failure that prevents connection string resolution.
  3. Use the resource's ConnectionStringExpression directly in the health check instead of the cached local.
Defensive patterns

Strategy: try-catch

Try / catch

try { await healthCheckService.CheckHealthAsync(); } catch (InvalidOperationException ex) when (ex.Message.Contains("Connection string is unavailable")) { logger.LogWarning("Oracle health check ran before connection string resolved; retry after startup."); }

Prevention

When it happens

Trigger: Health check executes before the ConnectionStringAvailableEvent callback assigned the connectionString local (e.g. resource unhealthy before connection string resolution, or event never fired).

Common situations: AppHost startup races where the health check runs early; the connection-string event never fired due to a failed resource start; inspection of health status during startup.

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

Appendix: source

Thrown at src/Aspire.Hosting.Oracle/OracleDatabaseBuilderExtensions.cs:57

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

        var oracleDatabaseServer = new OracleDatabaseServerResource(name, passwordParameter);

        string? connectionString = null;

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

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

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

        return builder.AddResource(oracleDatabaseServer)
                      .WithEndpoint(port: port, targetPort: 1521, name: OracleDatabaseServerResource.PrimaryEndpointName)
                      .WithImage(OracleContainerImageTags.Image, OracleContainerImageTags.Tag)
                      .WithImageRegistry(OracleContainerImageTags.Registry)
                      .WithIconName("DatabaseMultiple")
                      .WithEnvironment(context =>
                      {
                          context.EnvironmentVariables[PasswordEnvVarName] = oracleDatabaseServer.PasswordParameter;
                      })
                      .WithHealthCheck(healthCheckKey);
    }

    /// <summary>
    /// Adds a Oracle Database database to the application model.
    /// </summary>
    /// <param name="builder">The Oracle Database server resource builder.</param>
    /// <param name="name">The name of the resource. This name will be used as the connection string name when referenced in a dependency.</param>

View on GitHub (pinned to 25830f84bd)