t8y2/dbx · error · IllegalArgumentException

Client certificate and key must be provided together

Error message

Client certificate and key must be provided together

What it means

MongoAgent's configureBuilder validates TLS client authentication options: a client certificate path without its private key path (or vice versa) is invalid, since mTLS requires both. The XOR check on the resolved cert/key paths throws IllegalArgumentException immediately during connection setup.

Source

Thrown at agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java:118

        return json == null || json.isBlank() ? null : Document.parse(json);
    }

    static MongoClientSettings.Builder configureBuilder(JsonObject connObj) {
        String host = connObj.has("host") ? connObj.get("host").getAsString() : "127.0.0.1";
        int port = connObj.has("port") ? connObj.get("port").getAsInt() : 27017;
        String username = coalesce(stringOrNull(connObj, "username"));
        String password = coalesce(stringOrNull(connObj, "password"));
        String authDatabase = authenticationDatabase(connObj);
        String connectionString = stringOrNull(connObj, "connection_string");
        boolean ssl = connObj.has("ssl") && !connObj.get("ssl").isJsonNull() && connObj.get("ssl").getAsBoolean();
        String caCertPath = stringOrNull(connObj, "ca_cert_path");
        String clientCertPath = firstNonBlank(
            stringOrNull(connObj, "client_cert_path"), stringOrNull(connObj, "cert_path"));
        String clientKeyPath = firstNonBlank(
            stringOrNull(connObj, "client_key_path"), stringOrNull(connObj, "key_path"));

        if ((clientCertPath == null) != (clientKeyPath == null)) {
            throw new IllegalArgumentException("Client certificate and key must be provided together");
        }

        MongoClientSettings.Builder builder = MongoClientSettings.builder();
        if (connectionString != null && !connectionString.isBlank()) {
            builder.applyConnectionString(new ConnectionString(connectionString));
        } else {
            builder.applyToClusterSettings(
                settings -> settings.hosts(Collections.singletonList(new ServerAddress(host, port))));
            if (!username.isBlank()) {
                builder.credential(MongoCredential.createCredential(username, authDatabase, password.toCharArray()));
            }
        }

        if (ssl) {
            applyTlsSettings(builder, caCertPath, clientCertPath, clientKeyPath);
        }

        return builder;

View on GitHub (pinned to c0390bff16)

Solutions

  1. Provide both the client certificate and its private key paths in the connection object.
  2. Check which config key names you used — client_cert_path/cert_path and client_key_path/key_path are both accepted, but both sides must resolve.
  3. Verify the key file actually exists and is mounted/readable in your environment.
  4. If the key is embedded in a combined PEM, point both options at it or use the connection string's tlsCertificateKeyFile instead.

Example fix

// before
{"connection": {"connection_string": "mongodb://host", "client_cert_path": "/etc/ssl/client.pem"}}
// after
{"connection": {"connection_string": "mongodb://host", "client_cert_path": "/etc/ssl/client.pem", "client_key_path": "/etc/ssl/client-key.pem"}}
Defensive patterns

Strategy: validation

Validate before calling

function validateMtlsPair(conn) {
  const cert = conn.client_cert_path ?? conn.cert_path;
  const key = conn.client_key_path ?? conn.key_path;
  if ((cert != null) !== (key != null)) {
    throw new Error('Client certificate and key must be provided together');
  }
  return true;
}

Type guard

function hasCompleteMtlsConfig(conn) {
  const cert = conn?.client_cert_path ?? conn?.cert_path;
  const key = conn?.client_key_path ?? conn?.key_path;
  return (cert == null) === (key == null);
}

Try / catch

try {
  agent.connect(mongoParams);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("certificate and key must be provided together")) {
    // fix the connection object to include both client_cert_path and client_key_path, then retry
  } else { throw e; }
}

Prevention

When it happens

Trigger: Passing client_cert_path/cert_path without client_key_path/key_path (or the reverse) in the MongoDB connection object; a blank/whitespace value making one path null while the other is set.

Common situations: Copy-pasting a config sample with only the cert; secrets manager mounting the cert but not the key (wrong file permissions); renaming keys in config (cert_path vs client_cert_path) so only one resolves via firstNonBlank; mTLS setups where the key is embedded elsewhere.

Understand the failure class

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/fbada46b30fedf9b. Report an issue: GitHub.