When monitoring MongoDB 3.x instances from Nagios XI using the built-in check_mongodb.py plugin (originally written for MongoDB 2.x and older versions of pymongo), two issues commonly surface:

  1. An uncaught Python AttributeError: 'ConnectionFailure' object has no attribute 'strip' masking the underlying connection or authentication failure.
  2. Authentication failure (AuthenticationFailed: MONGODB-CR credentials missing in the user document) caused by MongoDB 3.0+ switching its default password hash mechanism from MONGODB-CR to SCRAM-SHA-1.

This post walks through diagnosing and resolving both issues.


Issue 1: AttributeError: 'ConnectionFailure' object has no attribute 'strip'

Symptom

Running check_mongodb.py from /usr/local/nagios/libexec crashes with a Python traceback instead of returning a clean Nagios status message:

[ahmed@localhost libexec]$ ./check_mongodb.py -H 192.168.94.137 -P 27017 -u admin -p REPLACE_PASSWORD
Traceback (most recent call last):
  File "./check_mongodb.py", line 1372, in <module>
    sys.exit(main(sys.argv[1:]))
  File "./check_mongodb.py", line 196, in main
    err, con = mongo_connect(host, port, ssl, user, passwd, replicaset)
  File "./check_mongodb.py", line 294, in mongo_connect
    return exit_with_general_critical(e), None
  File "./check_mongodb.py", line 310, in exit_with_general_critical
    if e.strip() == "not master":
AttributeError: 'ConnectionFailure' object has no attribute 'strip'

Root Cause & Fix

In exit_with_general_critical(e), the plugin assumes e is a str and calls e.strip(). When pymongo raises a ConnectionFailure or OperationFailure exception instance directly, calling .strip() on the exception object raises AttributeError.

Open /usr/local/nagios/libexec/check_mongodb.py around line 310 and convert e (or remove .strip()) before comparing:

# Before (line 310):
else:
    if e.strip() == "not master":
        print "UNKNOWN - Could not get data from server:", e
        return 3

# After:
else:
    if str(e).strip() == "not master":
        print "UNKNOWN - Could not get data from server:", e
        return 3

With that fix in place, check_mongodb.py prints the actual MongoDB error message:

[ahmed@localhost libexec]$ ./check_mongodb_2.py -H 192.168.94.138 -P 27017 -u admin -p REPLACE_PASSWORD -A databases -W 5 -C 10
CRITICAL - General MongoDB Error: command SON([('authenticate', 1), ('user', u'admin'), ('nonce', u'37a502d665186449'), ('key', u'd8c683f98a5e720c28a8007018ed7414')]) failed: auth failed

Issue 2: AuthenticationFailed: MONGODB-CR credentials missing in the user document

Symptom

When check_mongodb.py attempts to authenticate against MongoDB 3.x, the plugin returns failed: auth failed, and /var/log/mongodb/mongod.log on the MongoDB server logs:

2016-09-14T19:11:32.892-0700 I NETWORK  [initandlisten] connection accepted from 192.168.94.130:48657 #115 (2 connections now open)
2016-09-14T19:11:32.894-0700 I ACCESS   [conn115] authenticate db: admin { authenticate: 1, user: "admin", nonce: "xxx", key: "xxx" }
2016-09-14T19:11:32.894-0700 I ACCESS   [conn115] Failed to authenticate admin@admin with mechanism MONGODB-CR: AuthenticationFailed: MONGODB-CR credentials missing in the user document
2016-09-14T19:11:32.895-0700 I NETWORK  [conn115] end connection 192.168.94.130:48657 (1 connection now open)

Root Cause

  • MongoDB 2.6 and earlier used the MONGODB-CR challenge-response authentication mechanism (authSchema version 3).
  • MongoDB 3.0+ switched to SCRAM-SHA-1 (authSchema version 5) and stopped generating MONGODB-CR credentials on newly created user documents.
  • If the Nagios XI server has an older pymongo package installed (pymongo < 2.8), pymongo only knows how to authenticate via MONGODB-CR, which fails against MongoDB 3.0+ user accounts.

Upgrading pymongo to 2.8+ (or 3.x+) on the Nagios XI host enables SCRAM-SHA-1 support in the Python driver without weakening MongoDB’s authentication schema:

sudo pip install --upgrade pymongo

Option B (Legacy Test Workaround): Downgrade authSchema to Version 3 (MONGODB-CR)

In an isolated test lab where the Nagios client’s pymongo library cannot be updated, you can switch MongoDB 3.2’s admin.system.version (authSchema) from 5 to 3 and recreate the monitoring user so MONGODB-CR credentials are stored (do not run db.system.users.remove({}) on a production database):

use admin
var schema = db.system.version.findOne({ "_id" : "authSchema" })
schema.currentVersion = 3
db.system.version.save(schema)

After updating currentVersion to 3, drop and recreate the monitoring user so MongoDB generates MONGODB-CR credentials for that account. (Note: MONGODB-CR was removed entirely in MongoDB 4.0+.)

References