<!-- llms-explorer concept facts · https://llms-explorer.com/tree/pinned-aspire-mongodb-single-member-initialization-and-primary-readiness-boundaries/ · pack 2026-11-02 · ~3712 tokens -->

# Pinned Aspire MongoDB single-member initialization and primary-readiness boundaries

> Source-anchored research for Pinned Aspire MongoDB single-member initialization and primary-readiness boundaries. Run status: COMPLETED.

Parent: [MongoDB Drivers](https://llms-explorer.com/tree/mongodb-drivers/) · 5 facets · 19 facts · page: https://llms-explorer.com/tree/pinned-aspire-mongodb-single-member-initialization-and-primary-readiness-boundaries/

## Structure and components

- ValidateConfiguration accepts an existing configuration only when its set _id matches, it contains exactly one member, and that member host matches. It ignores additional server-populated fields and performs no rewriting. The fixtures assert an accepted configuration with existing version, priority and heartbeat settings is unchanged, and that a different set name, an old host or multiple members throws without mutation. (high confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBSingleMemberReplicaSet.cs) · [also](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/tests/Aspire.Hosting.MongoDB.Tests/SingleMemberReplicaSetTests.cs)
- InitializeAndWaitForPrimaryAsync passes the replSetGetStatus reply to IsPrimary. IsPrimary tests the supplied status document and returns true only when its set name matches the expected name, myState equals 1, and it contains exactly one member. The readiness fixture asserts true for that combination and false for state 2, another set name, or two members. (high confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBSingleMemberReplicaSet.cs) · [also](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/tests/Aspire.Hosting.MongoDB.Tests/SingleMemberReplicaSetTests.cs)

## How it works

- BuildConnectionString uses the normal server endpoint, URI-escapes configured credentials and a database name, and adds authSource and authMechanism when a password exists. MongoDBDatabaseResource obtains both its connection string and Uri from Parent.BuildConnectionString(DatabaseName), preserving the same server connection construction with a database path. (high confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBServerResource.cs) · [also](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBDatabaseResource.cs) · [also](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/tests/Aspire.Hosting.MongoDB.Tests/SingleMemberReplicaSetTests.cs)
- InitializeAndWaitForPrimaryAsync checks cancellation before issuing commands. It reads replSetGetConfig with ReadPreference.Nearest; only a MongoCommandException whose CodeName is NotYetInitialized triggers replSetInitiate with the requested set identity and one member whose _id is 0 and whose host is the supplied loopback address. It then loops to read and validate configuration before testing primary status. (low confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBSingleMemberReplicaSet.cs)
- The simple API rejects a server that already belongs to advanced membership. Conversely, WithMember rejects a server carrying the single-member annotation even when the set names match, and its diagnostic disallows migrating existing single-member data. Fixtures assert both directions reject without modifying member annotations; the advanced-adoption fixture also checks the password and empty membership list. (high confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs) · [also](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/ReplicaSet/MongoDBReplicaSetBuilderExtensions.cs) · [also](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/tests/Aspire.Hosting.MongoDB.Tests/SingleMemberReplicaSetTests.cs)

## Problems, failure modes and limitations

- WithReplicaSet registers MongoDBSingleMemberReplicaSet.InitializeAsync through OnInitializeResource. The initializer watches notifications for its own resource and starts an attempt only when the observed state changes into Running; repeated Running observations do not start another attempt. Its source comment explains that awaiting ResourceReadyEvent would deadlock because primary election is a prerequisite for resource health. After a handled initialization failure or success, the watcher remains active and updates wasRunning. Another attempt requires a later observed non-Running state followed by Running; the comment names failed or recreated container restarts as the intended retry trigger. (medium confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs) · [also](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBSingleMemberReplicaSet.cs)
- MyMongoDbHealthCheck first returns Unhealthy when the single-member annotation has an InitializationError. After that error is cleared, it runs replSetGetStatus against the authentication database with ReadPreference.Nearest and uses IsPrimary to choose Healthy or an unhealthy writable-single-member-primary message. The fixture asserts the initial and resource-specific initialization errors yield Unhealthy; the helper fixture separately checks the primary-status predicate. (high confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs) · [also](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBSingleMemberReplicaSet.cs) · [also](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/tests/Aspire.Hosting.MongoDB.Tests/SingleMemberReplicaSetTests.cs)
- The timeout branch catches OperationCanceledException only when the linked stopping token has not been cancelled and records failure to initialize and elect a primary within 90 seconds and advises restarting the resource. A distinct catch for MongoException, TimeoutException or DistributedApplicationException records initialization failure with container-log, volume and credential guidance. Neither branch clears InitializationError. (low confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBSingleMemberReplicaSet.cs)
- The initializer links the supplied cancellation token with ApplicationStopping. An outer OperationCanceledException catch handles stopping cancellation without recording the 90-second timeout error. The helper checks cancellation before commands and propagates the token into MongoDB commands and delays. The cancellation fixture supplies a pre-cancelled token and asserts OperationCanceledException from the helper. (medium confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBSingleMemberReplicaSet.cs) · [also](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/tests/Aspire.Hosting.MongoDB.Tests/SingleMemberReplicaSetTests.cs)

## Comparisons and alternatives

- If replSetInitiate races another initializer and returns AlreadyInitialized, the helper retries by reading and validating configuration rather than forcing a reconfiguration. MongoConnectionException and TimeoutException are also retried; the loop delays one second between unsuccessful iterations. The source explicitly scopes Running to container startup, which may precede acceptance of authenticated commands. (low confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBSingleMemberReplicaSet.cs)

## Facts and statements

- The pinned WithReplicaSet implementation returns the existing MongoDBServerResource builder. Its model fixture asserts repeated calls return the same builder, preserve the password parameter and existing database parent, add no separate logical replica-set resource, and leave one single-member annotation and one proxied endpoint with an unallocated host port and target port 27017. (high confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs) · [also](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/tests/Aspire.Hosting.MongoDB.Tests/SingleMemberReplicaSetTests.cs)
- WithReplicaSet defaults the set name to an existing configured name or the resource name. Repeating the same name is idempotent; changing it uses an ordinal case-sensitive comparison and throws InvalidOperationException. The case-sensitivity fixture asserts that attempting RS0 after rs0 leaves annotations and the configured name unchanged. (high confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs) · [also](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/tests/Aspire.Hosting.MongoDB.Tests/SingleMemberReplicaSetTests.cs)
- WithReplicaSet generates a secret key-file parameter unless a key-file annotation already exists, then configures bind-all addressing and --replSet. The explicit-key fixture asserts that the provided key and /etc/custom.key remain in use, that rs0 survives a subsequent nameless call, and that no additional key parameter appears. (high confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs) · [also](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/tests/Aspire.Hosting.MongoDB.Tests/SingleMemberReplicaSetTests.cs)
- A server with a replica-set name receives directConnection=true. The single-member annotation suppresses the secondaryPreferred read-preference option used for advanced members. The no-developer-certificate fixture parses both server and database URIs and asserts direct connections, ReadPreference.Primary, the configured credentials and host port, the appropriate database path, and matching Uri connection properties. (high confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBServerResource.cs) · [also](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/tests/Aspire.Hosting.MongoDB.Tests/SingleMemberReplicaSetTests.cs)
- The single-member path does not require a developer certificate according to its method documentation. TLS URI configuration is conditional: BuildConnectionString resolves tls=true lazily from the endpoint TLS state. The no-developer-certificate fixture asserts TlsEnabled and TlsAllowInvalidCertificates are false while server and database connections remain direct and use primary read preference. These are wrapper configuration observations. (high confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs) · [also](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBServerResource.cs) · [also](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/tests/Aspire.Hosting.MongoDB.Tests/SingleMemberReplicaSetTests.cs)
- WithReplicaSet invokes ThrowIfPublishMode before adding its key-file or replica-set annotations. The guard tests builder.ExecutionContext.IsPublishMode and throws NotSupportedException; its diagnostic says publishing and deploying are unsupported and this feature is implemented only for local AppHost runs. The publish-mode fixture asserts annotations and resources remain unchanged after rejection. (high confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs) · [also](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/tests/Aspire.Hosting.MongoDB.Tests/SingleMemberReplicaSetTests.cs)
- Each Running-transition attempt resets InitializationError to a waiting message, links a 90-second timeout to stopping, resolves the resource connection string, and sets both ServerSelectionTimeout and ConnectTimeout to 2 seconds. It clears InitializationError only after InitializeAndWaitForPrimaryAsync returns; a successful connection or container Running state alone does not clear the gate. (low confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBSingleMemberReplicaSet.cs)
- The initializer targets the admin authentication database and constructs the configured member address as localhost plus resource.PrimaryEndpoint.TargetPort. The source explains that loopback remains stable across container and AppHost restarts with changing host ports, while directConnection clients avoid discovering that internal address. This distinguishes the persisted member address from the client-facing allocated endpoint. (medium confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBServerResource.cs) · [also](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBSingleMemberReplicaSet.cs)
- AddDatabase retains a database child resource and its separate AddMongoDb health registration, while AddMongoDB passes a late-resolved single-member annotation to AddMyMongoDb for the server health check. The primary-election gate described here is the server-specific branch of MyMongoDbHealthCheck; the shown database registration is a separate health check. (low confidence) — [source](https://raw.githubusercontent.com/dotnet/aspire/0efbfcb095bf85ccf89678193d64b46022e7657e/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs)
