Problem connection in docker driver 3.4.x on a server configured as replicaset

Hi,

When a try to connect a dockerized application ussing the .net driver 3.4.x into a mongodb server 8.0.3 also dockerized and configured as replicaset the driver has a timeout and it can’t connect to the mongo server.

If i use a dockerized mongo server that is not replica set or the same dockerized application with driver 2.30.0 the application can connect to the mongo server.

The error when mongo server is configured as replica set

LogRecord.Exception: System.TimeoutException: A timeout occurred after 30000ms selecting a server using CompositeServerSelector{ Selectors = ReadPreferenceServerSelector{ ReadPreference = { Mode : Primary } }, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 }, OperationsCountServerSelector }. Client view of cluster state is { ClusterId : “1”, Type : “Unknown”, State : “Connected”, Servers : [{ ServerId: “{ ClusterId : 1, EndPoint : “Unspecified/mongodb:27017” }”, EndPoint: “Unspecified/mongodb:27017”, ReasonChanged: “Heartbeat”, State: “Connected”, ServerVersion: 8.0.0, TopologyVersion: { “processId” : { “$oid” : “688ce4d50ca1a2ea3f747bae” }, “counter” : 0 }, Type: “ReplicaSetGhost”, WireVersionRange: “[0, 25]”, LastHeartbeatTimestamp: “2025-08-01T16:03:45.4218373Z”, LastUpdateTimestamp: “2025-08-01T16:03:45.4218387Z” }] }.
2025-08-01T16:03:55.437806989Z at MongoDB.Driver.Core.Clusters.Cluster.ThrowTimeoutException(IServerSelector selector, ClusterDescription description)
2025-08-01T16:03:55.437808621Z at MongoDB.Driver.Core.Clusters.Cluster.WaitForDescriptionChangedHelper.HandleCompletedTask(Task completedTask)
2025-08-01T16:03:55.437809603Z at MongoDB.Driver.Core.Clusters.Cluster.WaitForDescriptionChangedAsync(IServerSelector selector, ClusterDescription description, Task descriptionChangedTask, TimeSpan timeout, CancellationToken cancellationToken)
2025-08-01T16:03:55.437810613Z at MongoDB.Driver.Core.Clusters.Cluster.SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken)
2025-08-01T16:03:55.437811605Z at MongoDB.Driver.Core.Clusters.IClusterExtensions.SelectServerAndPinIfNeededAsync(IClusterInternal cluster, ICoreSessionHandle session, IServerSelector selector, IReadOnlyCollection1 deprioritizedServers, CancellationToken cancellationToken) 2025-08-01T16:03:55.437812620Z at MongoDB.Driver.Core.Bindings.ReadPreferenceBinding.GetReadChannelSourceAsync(IReadOnlyCollection1 deprioritizedServers, CancellationToken cancellationToken)
2025-08-01T16:03:55.437813547Z at MongoDB.Driver.Core.Operations.RetryableReadContext.InitializeAsync(CancellationToken cancellationToken)
2025-08-01T16:03:55.437814720Z at MongoDB.Driver.Core.Operations.RetryableReadContext.CreateAsync(IReadBinding binding, Boolean retryRequested, CancellationToken cancellationToken)
2025-08-01T16:03:55.437815621Z at MongoDB.Driver.Core.Operations.FindOperation1.ExecuteAsync(IReadBinding binding, CancellationToken cancellationToken) 2025-08-01T16:03:55.437816479Z at MongoDB.Driver.OperationExecutor.ExecuteReadOperationAsync[TResult](IReadBinding binding, IReadOperation1 operation, CancellationToken cancellationToken)
2025-08-01T16:03:55.437817357Z at MongoDB.Driver.MongoCollectionImpl1.ExecuteReadOperationAsync[TResult](IClientSessionHandle session, IReadOperation1 operation, ReadPreference readPreference, CancellationToken cancellationToken)
2025-08-01T16:03:55.437826757Z at MongoDB.Driver.MongoCollectionImpl1.UsingImplicitSessionAsync[TResult](Func2 funcAsync, CancellationToken cancellationToken)

With driver 2.30.0 and 3.4.2 this configuration works fine for a dockerize app

services:

MongoDB

mongodb:
image: mongo:8.0.3
container_name: tenant-management-mongodb
restart: unless-stopped
ports:
- “27017:27017”

With this configuration the dokerize app only works with driver 2.30.0

services:

MongoDB

mongodb:
image: mongo:8.0.3
command: mongod --replSet rs-local
container_name: tenant-management-mongodb
restart: unless-stopped
ports:
- “27017:27017”

Please, any suggestion?

Hi @Carretero_Ruben,

If you’re using Docker in a non production environment, you can use the directConnection=true option to connect to your replica set. For production use cases, we recommend configuring the cluster to make each MongoDB instance accessible outside of the Docker virtual network as mentioned here. Hope that helps.

Thanks,

Rishit.

Thanks for you reply @Rishit_Bhatia but it’s not working.

directConnection=true works fine when you are building your app on windows and using a docker mongodb like in the integration test with testcointainers. In fact in the last version of testcontainers added the directConnection=true to the connection string when the container is configured on replica set mode.

But in the scenario mondog(docker) ← app(docker, driver 3.4.x) doesn’t works.

Please coould you run some internal test to verify this issue? Thanks.

Using a local DNS server for Docker and a srv connection string, the application can connect successfully. The replicaset had to be modified to look like this. Is there an easier way to do this, like with the 2.30.0 driver?

{
	"set" : "rs-local",
	"date" : ISODate("2025-08-03T20:18:02.781+02:00"),
	"myState" : 1,
	"term" : 1,
	"syncSourceHost" : "",
	"syncSourceId" : -1,
	"heartbeatIntervalMillis" : 2000,
	"majorityVoteCount" : 1,
	"writeMajorityCount" : 1,
	"votingMembersCount" : 1,
	"writableVotingMembersCount" : 1,
	"optimes" : {
		"lastCommittedOpTime" : {
			"ts" : Timestamp({ t: 1754245073, i: 1 }),
			"t" : 1
		},
		"lastCommittedWallTime" : ISODate("2025-08-03T20:17:53.658+02:00"),
		"readConcernMajorityOpTime" : {
			"ts" : Timestamp({ t: 1754245073, i: 1 }),
			"t" : 1
		},
		"appliedOpTime" : {
			"ts" : Timestamp({ t: 1754245073, i: 1 }),
			"t" : 1
		},
		"durableOpTime" : {
			"ts" : Timestamp({ t: 1754245073, i: 1 }),
			"t" : 1
		},
		"writtenOpTime" : {
			"ts" : Timestamp({ t: 1754245073, i: 1 }),
			"t" : 1
		},
		"lastAppliedWallTime" : ISODate("2025-08-03T20:17:53.658+02:00"),
		"lastDurableWallTime" : ISODate("2025-08-03T20:17:53.658+02:00"),
		"lastWrittenWallTime" : ISODate("2025-08-03T20:17:53.658+02:00")
	},
	"lastStableRecoveryTimestamp" : Timestamp({ t: 1754245053, i: 1 }),
	"electionCandidateMetrics" : {
		"lastElectionReason" : "electionTimeout",
		"lastElectionDate" : ISODate("2025-08-03T20:17:33.604+02:00"),
		"electionTerm" : 1,
		"lastCommittedOpTimeAtElection" : {
			"ts" : Timestamp({ t: 1754245053, i: 1 }),
			"t" : -1
		},
		"lastSeenWrittenOpTimeAtElection" : {
			"ts" : Timestamp({ t: 1754245053, i: 1 }),
			"t" : -1
		},
		"lastSeenOpTimeAtElection" : {
			"ts" : Timestamp({ t: 1754245053, i: 1 }),
			"t" : -1
		},
		"numVotesNeeded" : 1,
		"priorityAtElection" : 1,
		"electionTimeoutMillis" : 10000,
		"newTermStartDate" : ISODate("2025-08-03T20:17:33.641+02:00"),
		"wMajorityWriteAvailabilityDate" : ISODate("2025-08-03T20:17:33.709+02:00")
	},
	"members" : [
		{
			"_id" : 0,
			"name" : "mongodb.tenant-management.local:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 48,
			"optime" : {
				"ts" : Timestamp({ t: 1754245073, i: 1 }),
				"t" : 1
			},
			"optimeDate" : ISODate("2025-08-03T20:17:53.000+02:00"),
			"optimeWritten" : {
				"ts" : Timestamp({ t: 1754245073, i: 1 }),
				"t" : 1
			},
			"optimeWrittenDate" : ISODate("2025-08-03T20:17:53.000+02:00"),
			"lastAppliedWallTime" : ISODate("2025-08-03T20:17:53.658+02:00"),
			"lastDurableWallTime" : ISODate("2025-08-03T20:17:53.658+02:00"),
			"lastWrittenWallTime" : ISODate("2025-08-03T20:17:53.658+02:00"),
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "Could not find member to sync from",
			"electionTime" : Timestamp({ t: 1754245053, i: 2 }),
			"electionDate" : ISODate("2025-08-03T20:17:33.000+02:00"),
			"configVersion" : 1,
			"configTerm" : 1,
			"self" : true,
			"lastHeartbeatMessage" : ""
		}
	],
	"ok" : 1,
	"$clusterTime" : {
		"clusterTime" : Timestamp({ t: 1754245073, i: 1 }),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : 0
		}
	},
	"operationTime" : Timestamp({ t: 1754245073, i: 1 })
}

Without dns server de rs config is this :slight_smile:

{
	"set" : "rs-local",
	"date" : ISODate("2025-08-03T20:31:47.827+02:00"),
	"myState" : 1,
	"term" : 2,
	"syncSourceHost" : "",
	"syncSourceId" : -1,
	"heartbeatIntervalMillis" : 2000,
	"majorityVoteCount" : 1,
	"writeMajorityCount" : 1,
	"votingMembersCount" : 1,
	"writableVotingMembersCount" : 1,
	"optimes" : {
		"lastCommittedOpTime" : {
			"ts" : Timestamp({ t: 1754245900, i: 1 }),
			"t" : 2
		},
		"lastCommittedWallTime" : ISODate("2025-08-03T20:31:40.622+02:00"),
		"readConcernMajorityOpTime" : {
			"ts" : Timestamp({ t: 1754245900, i: 1 }),
			"t" : 2
		},
		"appliedOpTime" : {
			"ts" : Timestamp({ t: 1754245900, i: 1 }),
			"t" : 2
		},
		"durableOpTime" : {
			"ts" : Timestamp({ t: 1754245900, i: 1 }),
			"t" : 2
		},
		"writtenOpTime" : {
			"ts" : Timestamp({ t: 1754245900, i: 1 }),
			"t" : 2
		},
		"lastAppliedWallTime" : ISODate("2025-08-03T20:31:40.622+02:00"),
		"lastDurableWallTime" : ISODate("2025-08-03T20:31:40.622+02:00"),
		"lastWrittenWallTime" : ISODate("2025-08-03T20:31:40.622+02:00")
	},
	"lastStableRecoveryTimestamp" : Timestamp({ t: 1754245743, i: 1 }),
	"electionCandidateMetrics" : {
		"lastElectionReason" : "electionTimeout",
		"lastElectionDate" : ISODate("2025-08-03T20:31:10.617+02:00"),
		"electionTerm" : 2,
		"lastCommittedOpTimeAtElection" : {
			"ts" : Timestamp({ t: 0, i: 0 }),
			"t" : -1
		},
		"lastSeenWrittenOpTimeAtElection" : {
			"ts" : Timestamp({ t: 1754245743, i: 1 }),
			"t" : 1
		},
		"lastSeenOpTimeAtElection" : {
			"ts" : Timestamp({ t: 1754245743, i: 1 }),
			"t" : 1
		},
		"numVotesNeeded" : 1,
		"priorityAtElection" : 1,
		"electionTimeoutMillis" : 10000,
		"newTermStartDate" : ISODate("2025-08-03T20:31:10.621+02:00"),
		"wMajorityWriteAvailabilityDate" : ISODate("2025-08-03T20:31:10.724+02:00")
	},
	"members" : [
		{
			"_id" : 0,
			"name" : "localhost:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 37,
			"optime" : {
				"ts" : Timestamp({ t: 1754245900, i: 1 }),
				"t" : 2
			},
			"optimeDate" : ISODate("2025-08-03T20:31:40.000+02:00"),
			"optimeWritten" : {
				"ts" : Timestamp({ t: 1754245900, i: 1 }),
				"t" : 2
			},
			"optimeWrittenDate" : ISODate("2025-08-03T20:31:40.000+02:00"),
			"lastAppliedWallTime" : ISODate("2025-08-03T20:31:40.622+02:00"),
			"lastDurableWallTime" : ISODate("2025-08-03T20:31:40.622+02:00"),
			"lastWrittenWallTime" : ISODate("2025-08-03T20:31:40.622+02:00"),
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "Could not find member to sync from",
			"electionTime" : Timestamp({ t: 1754245870, i: 1 }),
			"electionDate" : ISODate("2025-08-03T20:31:10.000+02:00"),
			"configVersion" : 1,
			"configTerm" : 2,
			"self" : true,
			"lastHeartbeatMessage" : ""
		}
	],
	"ok" : 1,
	"$clusterTime" : {
		"clusterTime" : Timestamp({ t: 1754245900, i: 1 }),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : 0
		}
	},
	"operationTime" : Timestamp({ t: 1754245900, i: 1 })
}

Hi @Carretero_Ruben !

Could you please confirm that the problem exists (driver cannot connect to MongoDB) on your side when you run both (MongoDB and client application) in Docker? Could you please elaborate a little on the configuration? Is this the same Docker host? How connection string looks like? Does app sharing the same virtual network with MongoDB cluster?

Thanks,
Oleksandr

Hi @Oleksandr_Poliakov

The problem only occurs when the aplication is dockerized (not if you execute from windows) and you are using a local url (not if you use a srv connections string like in the production enviroments). The conexion string from de application is the same with the driver 2.30.0, nothing else change, only the driver version.

Docker.compose.yml

    environment:
      ASPNETCORE_ENVIRONMENT: Development
      ASPNETCORE_URLS: http://+:8080
      MongoDb__PrimaryConnectionString: mongodb://mongodb:27017
      MongoDb__SecondaryConnectionString: mongodb://mongodb:27017
      MongoDb__DatabaseName: COR_WriteDb

appsettings.Development.json

  "MongoDb": {
    "PrimaryConnectionString": "mongodb://mongodb:27017",
    "SecondaryConnectionString": "mongodb://mongodb:27017" //by default
  }

The configuration for the local docker is:

docker.compose.yml

  mongodb:
    image: mongo:8.0.12
    command: mongod --replSet rs-local --bind_ip_all
    container_name: tenant-management-mongodb
    restart: unless-stopped
    ports:
      - "27017:27017"
    environment:
      MONGO_INITDB_DATABASE: COR_WriteDb
    volumes:
      - mongodb_data:/data/db
      - ./mongo-init:/docker-entrypoint-initdb.d
    networks:
      - tenant-management-network

rs.status()

{
	"set" : "rs-local",
	"date" : ISODate("2025-08-03T20:31:47.827+02:00"),
	"myState" : 1,
	"term" : 2,
	"syncSourceHost" : "",
	"syncSourceId" : -1,
	"heartbeatIntervalMillis" : 2000,
	"majorityVoteCount" : 1,
	"writeMajorityCount" : 1,
	"votingMembersCount" : 1,
	"writableVotingMembersCount" : 1,
	"optimes" : {
		"lastCommittedOpTime" : {
			"ts" : Timestamp({ t: 1754245900, i: 1 }),
			"t" : 2
		},
		"lastCommittedWallTime" : ISODate("2025-08-03T20:31:40.622+02:00"),
		"readConcernMajorityOpTime" : {
			"ts" : Timestamp({ t: 1754245900, i: 1 }),
			"t" : 2
		},
		"appliedOpTime" : {
			"ts" : Timestamp({ t: 1754245900, i: 1 }),
			"t" : 2
		},
		"durableOpTime" : {
			"ts" : Timestamp({ t: 1754245900, i: 1 }),
			"t" : 2
		},
		"writtenOpTime" : {
			"ts" : Timestamp({ t: 1754245900, i: 1 }),
			"t" : 2
		},
		"lastAppliedWallTime" : ISODate("2025-08-03T20:31:40.622+02:00"),
		"lastDurableWallTime" : ISODate("2025-08-03T20:31:40.622+02:00"),
		"lastWrittenWallTime" : ISODate("2025-08-03T20:31:40.622+02:00")
	},
	"lastStableRecoveryTimestamp" : Timestamp({ t: 1754245743, i: 1 }),
	"electionCandidateMetrics" : {
		"lastElectionReason" : "electionTimeout",
		"lastElectionDate" : ISODate("2025-08-03T20:31:10.617+02:00"),
		"electionTerm" : 2,
		"lastCommittedOpTimeAtElection" : {
			"ts" : Timestamp({ t: 0, i: 0 }),
			"t" : -1
		},
		"lastSeenWrittenOpTimeAtElection" : {
			"ts" : Timestamp({ t: 1754245743, i: 1 }),
			"t" : 1
		},
		"lastSeenOpTimeAtElection" : {
			"ts" : Timestamp({ t: 1754245743, i: 1 }),
			"t" : 1
		},
		"numVotesNeeded" : 1,
		"priorityAtElection" : 1,
		"electionTimeoutMillis" : 10000,
		"newTermStartDate" : ISODate("2025-08-03T20:31:10.621+02:00"),
		"wMajorityWriteAvailabilityDate" : ISODate("2025-08-03T20:31:10.724+02:00")
	},
	"members" : [
		{
			"_id" : 0,
			"name" : "localhost:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 37,
			"optime" : {
				"ts" : Timestamp({ t: 1754245900, i: 1 }),
				"t" : 2
			},
			"optimeDate" : ISODate("2025-08-03T20:31:40.000+02:00"),
			"optimeWritten" : {
				"ts" : Timestamp({ t: 1754245900, i: 1 }),
				"t" : 2
			},
			"optimeWrittenDate" : ISODate("2025-08-03T20:31:40.000+02:00"),
			"lastAppliedWallTime" : ISODate("2025-08-03T20:31:40.622+02:00"),
			"lastDurableWallTime" : ISODate("2025-08-03T20:31:40.622+02:00"),
			"lastWrittenWallTime" : ISODate("2025-08-03T20:31:40.622+02:00"),
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "Could not find member to sync from",
			"electionTime" : Timestamp({ t: 1754245870, i: 1 }),
			"electionDate" : ISODate("2025-08-03T20:31:10.000+02:00"),
			"configVersion" : 1,
			"configTerm" : 2,
			"self" : true,
			"lastHeartbeatMessage" : ""
		}
	],
	"ok" : 1,
	"$clusterTime" : {
		"clusterTime" : Timestamp({ t: 1754245900, i: 1 }),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : 0
		}
	},
	"operationTime" : Timestamp({ t: 1754245900, i: 1 })
}

If you are using a local mongodb instaled on windows the problem persist. The only way that i found for using dockerized app with driver 3.4.0 is create a dns insternal server and use the SRV connections string,

Hi @Carretero_Ruben !

Thank you for providing more details.

From what I can see, your current configuration exposes single node only (even though we do not recommend such configuration for production usage because in event of failover your single exposed node might go down or turned to secondary, but anyway it’s still legit). It means you should use directConnection=true to connect that node. Could you please elaborate why this does not work for you? Have you run into an exception? Could you please provide the connection string you are using?

Thanks,
Oleksandr

Hi @Oleksandr_Poliakov this config is not for production, only for local development and the option directconnection doesn’t works.

The connection string is [quote=“Carretero_Ruben, post:6, topic:326657”]
mongodb://mongodb:27017
[/quote]

It’s doesn’t change and the mongodb docker configurarion neither. Only thw driver version from 2.30.0 to 3.4.x

Could you please elaborate on this statement:

option directconnection doesn’t works

Do you run into exception? Also provided connection string DOES NOT include directconnection option enabled. Could you please try to add directConnection=true to your connection string? So it will looks like: mongodb://mongodb:27017?directConnection=true. This will disable cluster topology discovery, so driver will directly connect to the provided endpoint (it will do exactly the same as v2.30.0).
Another possible reason: it seems like you are using virtual network for MongoDB containers, but not sure if you put your app container into the same network. Could you please make sure they are in the same network? Or you can try to connect via port mapped to the host if application container stared with --network=host: mongodb://localhost:27017?directConnection=true

Thanks,
Oleksandr