{"id":"816b63ab10fab843","repo":"mongodb/node-mongodb-native","slug":"all-values-of-tls-ssl-must-be-the-same","errorCode":null,"errorMessage":"All values of tls/ssl must be the same.","messagePattern":"All values of tls/ssl must be the same\\.","errorType":"exception","errorClass":"MongoParseError","httpStatus":null,"severity":"error","filePath":"src/connection_string.ts","lineNumber":356,"sourceCode":"\n  for (const key of allProvidedKeys) {\n    const values = [];\n    const objectOptionValue = objectOptions.get(key);\n    if (objectOptionValue != null) {\n      values.push(objectOptionValue);\n    }\n\n    const urlValues = urlOptions.get(key) ?? [];\n    values.push(...urlValues);\n    allProvidedOptions.set(key, values);\n  }\n\n  if (allProvidedOptions.has('tls') || allProvidedOptions.has('ssl')) {\n    const tlsAndSslOpts = (allProvidedOptions.get('tls') || [])\n      .concat(allProvidedOptions.get('ssl') || [])\n      .map(getBoolean.bind(null, 'tls/ssl'));\n    if (new Set(tlsAndSslOpts).size !== 1) {\n      throw new MongoParseError('All values of tls/ssl must be the same.');\n    }\n  }\n\n  checkTLSOptions(allProvidedOptions);\n\n  const unsupportedOptions = setDifference(\n    allProvidedKeys,\n    Array.from(Object.keys(OPTIONS)).map(s => s.toLowerCase())\n  );\n  if (unsupportedOptions.size !== 0) {\n    const optionWord = unsupportedOptions.size > 1 ? 'options' : 'option';\n    const isOrAre = unsupportedOptions.size > 1 ? 'are' : 'is';\n    throw new MongoParseError(\n      `${optionWord} ${Array.from(unsupportedOptions).join(', ')} ${isOrAre} not supported`\n    );\n  }\n\n  // Option parsing and setting","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/connection_string.ts#L338-L374","documentation":"Thrown when the driver resolves all `tls` and `ssl` values (from both URI query params and the options object) and finds inconsistent booleans. Because tls and ssl are aliases, mixing true/false across them is ambiguous and rejected. The check at connection_string.ts:355 builds a Set of resolved boolean values; size !== 1 means conflict.","triggerScenarios":"Passing URI '?tls=true' with options { ssl: false }, or '?ssl=false' with { tls: true }, or '?tls=true&ssl=false' in the same URI. Any combination resolving to conflicting booleans triggers it.","commonSituations":"Migrating from deprecated ssl to tls without removing the old flag; environment-specific config that toggles ssl in code while a base URI hardcodes tls; templated URIs that append tls unconditionally.","solutions":["Pick one option name (prefer tls) and use it consistently across URI and options object.","Remove either the tls or ssl entry so only one resolved boolean remains.","If you need TLS off, set tls=false everywhere consistently (and avoid ssl entirely)."],"exampleFix":"// before\nconst c = new MongoClient('mongodb://host:27017/?tls=true', { ssl: false });\n// after\nconst c = new MongoClient('mongodb://host:27017/?tls=false');","handlingStrategy":"validation","validationCode":"const hasTLS = new URL(uri).searchParams.has('tls');\nconst hasSSL = new URL(uri).searchParams.has('ssl');\nif ((hasTLS || 'tls' in opts) && (hasSSL || 'ssl' in opts)) {\n  throw new Error('Specify only tls OR ssl, not both');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Standardize on `tls` everywhere; treat `ssl` as deprecated.","Run a lint rule that rejects ssl: in connection config."],"tags":["connection-string","tls","configuration"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}