MongoDB.live, free & fully virtual. Register Now MongoDB.live, free & fully virtual. Register Now

Server sent an invalid nonce when making multiple rapid connections from C# driver

I recently added authentication to my development database, authenticating against the “admin” database, and using a username/password combination in my connection string, e.g. mongodb://username:password@server:27017. Almost immediately I started seeing connections failing to open with an exception showing “Server sent an invalid nonce”. To try and mitigate the problem I looked at the lifetime of my IMongoClient objects, and moved from instantiating many such objects to using a Singleton injected into my business services using the Microsoft.Extensions.DependencyInjection libraries. This hasn’t alleviated the issue. I set up the MongoClient in my Startup.cs using .AddSingleton<IMongoClient>(factory => new MongoClient(Configuration["Storage:MongoConnectionString"])). I know that the connection string is correct as it works in MongoDB Compass, and also because the first couple of calls through the driver work successfully; the issue starts occuring when multiple concurrent calls are in progress.

I am using the MongoDB .NET driver, version 2.11.0, under .NET Core 3.1.2. The problem occurs in my local environment running Windows 10, and also my staging environment running inside Docker on VMware Photon.

There are two components of the app that make connnections to MongoDB, both of which are ASP.Net Core applications, one serving an API for interactive usage of my applicaiton, and one running a Quartz scheduler for background processing. I’m running MongoDB 4.4.0 Community inside a Docker container.

My references to include the driver are:

<PackageReference Include="MongoDB.Bson" Version="2.11.0" />
<PackageReference Include="MongoDB.Driver" Version="2.11.0" />
<PackageReference Include="MongoDB.Driver.Core" Version="2.11.0" />

According to this post on the MongoDB Jira site I’m not the first person to experience this issue. Mathias Lorenzen suggested in the issue on Jira that he had reduced the number of errors he encountered with various fixes including recreating the user, using SCRAM-SHA-1, and increasing the maximum number of connections permitted on the server. With these changes in place, the issue still occurs for me.

I’m guessing that the problem is related to threading when used in conjunction with database authentication. I can’t, for obvious reasons, put this code into production use by disabling authentication to work around the problem, and equally the use of a synchronous model rather than async seems counter-productive. What steps can I take to try and resolve the authentication issues? Is this likely to be a bug in the Mongo C# driver, or am I simply using it wrong.

Insight on what I can try next, or alternative approaches, would be gratefully received.


Edit: Minimum reproducible example as requested:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using MongoDB.Driver;

namespace MongoDbIssueExample
{
    internal class Program
    {
        private static IServiceProvider services;

        private static IServiceProvider BuildDependencyInjector()
        {
            services = new ServiceCollection()
                .AddSingleton<TestThingsService>()
                .AddSingleton<IMongoClient>(factory => new MongoClient("mongodb://username:password@server:27017"))
                .BuildServiceProvider();

            return services;
        }

        private static async Task DoSeed()
        {
            var service = services.GetService<TestThingsService>();
            // Don't do these async as we'll never get any data in...
            service.CreateTestThings().Wait();
            service.CreateOtherTestThings().Wait();
        }

        private static async Task DoTest()
        {
            var service = services.GetService<TestThingsService>();

            var things = service.GetTestThings();
            var otherThings = service.GetOtherTestThings();

            Task.WaitAll(things, otherThings);
        }

        private static async Task Main(string[] args)
        {
            BuildDependencyInjector();

            await DoTest();
        }
    }

    public class TestThingsService
    {
        private readonly IMongoClient _client;
        private readonly IMongoDatabase _database;
        private readonly IMongoCollection<OtherTestThing> _otherTestThingsCollection;
        private readonly IMongoCollection<TestThing> _testThingsCollection;

        public TestThingsService(IMongoClient client)
        {
            _client = client;
            _database = _client.GetDatabase("Things");
            _testThingsCollection = _database.GetCollection<TestThing>("TestThings");
            _otherTestThingsCollection = _database.GetCollection<OtherTestThing>("OtherTestThings");
        }

        public async Task CreateOtherTestThings()
        {
            for (var item = 1; item <= 10000; item++)
            {
                var testThing = new OtherTestThing {Id = item, Name = $"Other thing no. {item}", WhenCreated = DateTime.UtcNow};
                await _otherTestThingsCollection.ReplaceOneAsync(f => f.Id == item, testThing, new ReplaceOptions {IsUpsert = true});
            }
        }

        public async Task CreateTestThings()
        {
            for (var item = 1; item <= 10000; item++)
            {
                var testThing = new TestThing {Id = item, Name = $"Thing no. {item}", WhenCreated = DateTime.UtcNow};
                await _testThingsCollection.ReplaceOneAsync(f => f.Id == item, testThing, new ReplaceOptions {IsUpsert = true});
            }
        }


        public async Task<List<OtherTestThing>> GetOtherTestThings()
        {
            return await _otherTestThingsCollection.Find(_ => true).ToListAsync();
        }

        public async Task<List<TestThing>> GetTestThings()
        {
            return await _testThingsCollection.Find(_ => true).ToListAsync();
        }
    }

    public class OtherTestThing
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime WhenCreated { get; set; }
    }

    public class TestThing
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime WhenCreated { get; set; }
    }
}

Requires references as follows:

		<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.6" />
		<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.6" />
		<PackageReference Include="MongoDB.Bson" Version="2.11.0" />
		<PackageReference Include="MongoDB.Driver" Version="2.11.0" />
		<PackageReference Include="MongoDB.Driver.Core" Version="2.11.0" />

Hi, you have found any solution, I have same problem when I upgrade my current solution to drivers latest version ?

So I can’t migrate my server to 4.4 :frowning:

Hi,

After some test, I finaly find if you create user without SCRAM-SHA-256 (my application user can only login with SCRAM-SHA-1), it work flawlessly.

I hope help you

Hi Herve,

Can you provide an example of how you create the user differently?

Would this work?

db.createUser(
   {
     user: "reportUser256",
     pwd: passwordPrompt(),   // Or  "<cleartext password>"
     roles: [ { role: "readWrite", db: "reporting" } ],
     mechanisms: [ "SCRAM-SHA-1" ]
   }
)

Same issue in my project.

Environment: .Net Core SDK 3.1.401, Mongodb.Driver 2.11.0
MongoDB Version:

mongos version v4.4.0
Build Info: {
    "version": "4.4.0",
    "gitVersion": "563487e100c4215e2dce98d0af2a6a5a2d67c5cf",
    "openSSLVersion": "OpenSSL 1.1.1d  10 Sep 2019",
    "modules": [],
    "allocator": "tcmalloc",
    "environment": {
        "distmod": "debian10",
        "distarch": "x86_64",
        "target_arch": "x86_64"
    }
}


This is the code:

var client = new MongoClient(_connection_string);;
var database = client.GetDatabase(Database_name);
var collection = database.GetCollection<T>(Collection_name);
var document_count = collection.EstimatedDocumentCount();

And the exception:

MongoDB.Driver.MongoAuthenticationException: Server sent an invalid nonce.
   at MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelper(CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Connections.BinaryConnection.Open(CancellationToken cancellationToken)
   at MongoDB.Driver.Core.ConnectionPools.ExclusiveConnectionPool.PooledConnection.Open(CancellationToken cancellationToken)
   at MongoDB.Driver.Core.ConnectionPools.ExclusiveConnectionPool.AcquiredConnection.Open(CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Servers.Server.GetChannel(CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Bindings.ServerChannelSource.GetChannel(CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Bindings.ChannelSourceHandle.GetChannel(CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Operations.RetryableReadContext.Initialize(CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Operations.RetryableReadContext.Create(IReadBinding binding, Boolean retryRequested, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Operations.CountOperation.Execute(IReadBinding binding, CancellationToken cancellationToken)
   at MongoDB.Driver.OperationExecutor.ExecuteReadOperation[TResult](IReadBinding binding, IReadOperation`1 operation, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.ExecuteReadOperation[TResult](IClientSessionHandle session, IReadOperation`1 operation, ReadPreference readPreference, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.ExecuteReadOperation[TResult](IClientSessionHandle session, IReadOperation`1 operation, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.<>c__DisplayClass43_0.<EstimatedDocumentCount>b__0(IClientSessionHandle session)
   at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSession[TResult](Func`2 func, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.EstimatedDocumentCount(EstimatedDocumentCountOptions options, CancellationToken cancellationToken)


Any advise?

Hi,
I got this error, and it’s resolved after create new user in that database, before I using use from admin database. Hope help for you.

Find more information:

Code:

var client = new MongoClient(_connection_string);;
var database = client.GetDatabase(Database_name);
var collection = database.GetCollection<T>(Collection_name);

Using mongodb.driver 2.11.0, it create 2 connections, when if using mongodb.driver 2.10.4, it create only 1 connection.

Now I back my projects to 2.10.4, still testing …

I revert to old version 2.10.4, no way to working with latest version.

Reverting to 2.10.4 seems to be the problem for me.
I’m sad and confused :confused:

Hi @DDA,

MongoDB.Driver.MongoAuthenticationException: Server sent an invalid nonce.

Looks like another user (Mark Weaver) reported this issue on CSHARP-3196. There is a patch that is currently in code review, please watch/up-vote the issue tracker to receive notifications on it.

Regards,
Wan.

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.