{"record":{"id":"87b87ed07ca2aac4","repo":"microsoft/aspire","slug":"resourcereadyevent-was-published-for-the-postgresserver-name","errorCode":null,"errorMessage":"ResourceReadyEvent was published for the '{postgresServer.Name}' resource but the connection string was null.","messagePattern":"ResourceReadyEvent was published for the '(.+?)' resource but the connection string was null\\.","errorType":"exception","errorClass":"DistributedApplicationException","httpStatus":null,"severity":"critical","filePath":"src/Aspire.Hosting.PostgreSQL/PostgresBuilderExtensions.cs","lineNumber":77,"sourceCode":"        var postgresServer = new PostgresServerResource(name, userName?.Resource, passwordParameter);\n\n        string? connectionString = null;\n\n        builder.Eventing.Subscribe<ConnectionStringAvailableEvent>(postgresServer, async (@event, ct) =>\n        {\n            connectionString = await postgresServer.GetConnectionStringAsync(ct).ConfigureAwait(false);\n\n            if (connectionString == null)\n            {\n                throw new DistributedApplicationException($\"ConnectionStringAvailableEvent was published for the '{postgresServer.Name}' resource but the connection string was null.\");\n            }\n        });\n\n        builder.Eventing.Subscribe<ResourceReadyEvent>(postgresServer, async (@event, ct) =>\n        {\n            if (connectionString is null)\n            {\n                throw new DistributedApplicationException($\"ResourceReadyEvent was published for the '{postgresServer.Name}' resource but the connection string was null.\");\n            }\n\n            // Non-database scoped connection string\n            using var npgsqlConnection = new NpgsqlConnection(connectionString + \";Database=postgres;\");\n\n            await npgsqlConnection.OpenAsync(ct).ConfigureAwait(false);\n\n            if (npgsqlConnection.State != System.Data.ConnectionState.Open)\n            {\n                throw new InvalidOperationException($\"Could not open connection to '{postgresServer.Name}'\");\n            }\n\n            foreach (var name in postgresServer.Databases.Keys)\n            {\n                if (builder.Resources.FirstOrDefault(n => string.Equals(n.Name, name, StringComparisons.ResourceName)) is PostgresDatabaseResource postgreDatabase)\n                {\n                    await CreateDatabaseAsync(npgsqlConnection, postgreDatabase, @event.Services, ct).ConfigureAwait(false);\n                }","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.PostgreSQL/PostgresBuilderExtensions.cs#L59-L95","documentation":"AddPostgres also subscribes to ResourceReadyEvent for the server resource to auto-create databases declared via WithDatabase. If the event fires but the cached connection string is still null, a DistributedApplicationException is thrown because database provisioning cannot proceed without a usable connection string. It indicates the connection-string event never populated the shared state before the resource was declared ready.","triggerScenarios":"ResourceReadyEvent fires for postgresServer while the ConnectionStringAvailableEvent callback has not (or failed to) set the connectionString local, e.g. when the resource reports ready without a resolved connection string.","commonSituations":"Startup ordering issues where the resource is marked ready before its connection string resolves; failed or skipped connection-string resolution due to configuration problems; using WithDatabase with a broken server resource.","solutions":["Fix the underlying reason the connection string did not resolve (missing parameters/endpoint config for the Postgres resource).","Update the AppHost/Aspire packages — some ordering issues between these events were fixed in later versions.","Avoid manually publishing ResourceReadyEvent for the resource."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await /* resource-ready dependent work */; } catch (DistributedApplicationException ex) when (ex.Message.Contains(\"ResourceReadyEvent was published\")) { logger.LogError(ex, \"Connection string was not resolved before resource became ready\"); throw; }","preventionTips":["Keep Aspire.Hosting packages up to date to pick up event-ordering fixes","Avoid custom resource lifecycle events that fire ready early","Resolve connection-string problems surfaced at the earlier event before adding WithDatabase databases"],"tags":["aspire","postgresql","eventing","race-condition"],"backgroundTag":"invalid-state-transition","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}