{"record":{"id":"5a46aa9d8eacddb0","repo":"microsoft/aspire","slug":"connection-string-is-unavailable-sqlserverbuilderextensions","errorCode":null,"errorMessage":"Connection string is unavailable","messagePattern":"Connection string is unavailable","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.SqlServer/SqlServerBuilderExtensions.cs","lineNumber":51,"sourceCode":"    /// <param name=\"password\">The parameter used to provide the administrator password for the SQL Server resource. If <see langword=\"null\"/> a random password will be generated.</param>\n    /// <param name=\"port\">The host port for the SQL Server.</param>\n    /// <returns>A reference to the <see cref=\"IResourceBuilder{T}\"/>.</returns>\n    /// <ats-returns>The resource builder.</ats-returns>\n    [AspireExport]\n    public static IResourceBuilder<SqlServerServerResource> AddSqlServer(this IDistributedApplicationBuilder builder, [ResourceName] string name, IResourceBuilder<ParameterResource>? password = null, int? port = null)\n    {\n        ArgumentNullException.ThrowIfNull(builder);\n        ArgumentException.ThrowIfNullOrEmpty(name);\n\n        // The password must be at least 8 characters long and contain characters from three of the following four sets: Uppercase letters, Lowercase letters, Base 10 digits, and Symbols\n        var passwordParameter = password?.Resource ?? ParameterResourceBuilderExtensions.CreateDefaultPasswordParameter(builder, $\"{name}-password\", minLower: 1, minUpper: 1, minNumeric: 1);\n\n        var sqlServer = new SqlServerServerResource(name, passwordParameter);\n\n        string? connectionString = null;\n\n        var healthCheckKey = $\"{name}_check\";\n        builder.Services.AddHealthChecks().AddSqlServer(sp => connectionString ?? throw new InvalidOperationException(\"Connection string is unavailable\"), name: healthCheckKey);\n\n        return builder.AddResource(sqlServer)\n                      .WithEndpoint(port: port, targetPort: 1433, name: SqlServerServerResource.PrimaryEndpointName)\n                      .WithImage(SqlServerContainerImageTags.Image, SqlServerContainerImageTags.Tag)\n                      .WithImageRegistry(SqlServerContainerImageTags.Registry)\n                      .WithIconName(\"DatabaseMultiple\")\n                      .WithEnvironment(\"ACCEPT_EULA\", \"Y\")\n                      .WithEnvironment(context =>\n                      {\n                          context.EnvironmentVariables[\"MSSQL_SA_PASSWORD\"] = sqlServer.PasswordParameter;\n                      })\n                      .WithHealthCheck(healthCheckKey)\n                      .OnConnectionStringAvailable(async (sqlServer, @event, ct) =>\n                      {\n                          connectionString = await sqlServer.GetConnectionStringAsync(ct).ConfigureAwait(false);\n\n                          if (connectionString == null)\n                          {","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.SqlServer/SqlServerBuilderExtensions.cs#L33-L69","documentation":"AddSqlServer registers an ASP.NET health check that resolves the SQL Server connection string from a captured local variable. That variable is only populated later, when the ConnectionStringAvailableEvent fires during resource startup. If the health check executes before that event has run (or the event failed to set it), the lambda throws this InvalidOperationException.","triggerScenarios":"The '{name}_check' health check runs while connectionString is still null: health checks executed before the SQL Server container started and published its connection string, or the OnConnectionStringAvailable callback did not run/complete (resource startup failed, event pipeline interrupted), or the health check is invoked in a context where the Aspire eventing never populated the connection string (e.g. running the health check outside normal AppHost orchestration).","commonSituations":"Health check probed by an external orchestrator/load balancer before the SQL Server resource is running; AppHost startup failure leaves the resource never reaching ConnectionStringAvailable; custom tooling invoking health checks against an AppHost where the resource is not started.","solutions":["Let the AppHost start the SQL Server resource and wait for it: reference the server from dependent resources via WithReference so they wait for availability instead of probing the health check early.","If you see this during normal startup, check the dashboard/logs for an earlier failure in the resource's ConnectionStringAvailable lifecycle (e.g. container failed to start, endpoint allocation failed) and fix the root cause.","Do not invoke the '{name}_check' health check from outside the AppHost's resource orchestration; it depends on Aspire eventing to populate the connection string.","If the resource never becomes healthy, verify the SQL Server container image can start (ACCEPT_EULA=Y is set, license accepted, port not conflicting)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure dependents reference the server so they wait for availability instead of probing early\nvar sql = builder.AddSqlServer(\"sql\");\nvar api = builder.AddProject<Projects.Api>(\"api\")\n    .WithReference(sql)\n    .WaitFor(sql); // avoids hitting the health check before the connection string exists","typeGuard":null,"tryCatchPattern":"try\n{\n    await healthCheckService.CheckHealthAsync(\"sql_check\");\n}\ncatch (InvalidOperationException ex) when (ex.Message == \"Connection string is unavailable\")\n{\n    // treat as 'not ready yet'; retry after the resource reaches Running/Healthy\n}","preventionTips":["Never invoke Aspire-registered resource health checks before the resource has started in the AppHost.","Use WithReference/WaitFor so dependent services start only after SQL Server is available.","Watch the dashboard for ConnectionStringAvailable failures — this health check error is usually downstream of one.","Keep the resource builder returned by AddSqlServer intact; the health check depends on its event callbacks."],"tags":["sqlserver","health-checks","connection-string","aspire"],"backgroundTag":"connection-string-unavailable","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}