{"record":{"id":"421ca4083d62bf18","repo":"mongodb/node-mongodb-native","slug":"text-record-may-only-set-any-of-valid-txt-recor","errorCode":null,"errorMessage":"Text record may only set any of: ${VALID_TXT_RECORDS.join(', ')}","messagePattern":"Text record may only set any of: (.+?)","errorType":"exception","errorClass":"MongoParseError","httpStatus":null,"severity":"error","filePath":"src/connection_string.ts","lineNumber":123,"sourceCode":"  // Use the result of resolving the TXT record and add options from there if they exist.\n  let record;\n  try {\n    record = await txtResolutionPromise;\n  } catch (error) {\n    if (error.code !== 'ENODATA' && error.code !== 'ENOTFOUND') {\n      throw error;\n    }\n    return hostAddresses;\n  }\n\n  if (record.length > 1) {\n    throw new MongoParseError('Multiple text records not allowed');\n  }\n\n  const txtRecordOptions = new URLSearchParams(record[0].join(''));\n  const txtRecordOptionKeys = [...txtRecordOptions.keys()];\n  if (txtRecordOptionKeys.some(key => !VALID_TXT_RECORDS.includes(key))) {\n    throw new MongoParseError(`Text record may only set any of: ${VALID_TXT_RECORDS.join(', ')}`);\n  }\n\n  if (VALID_TXT_RECORDS.some(option => txtRecordOptions.get(option) === '')) {\n    throw new MongoParseError('Cannot have empty URI params in DNS TXT Record');\n  }\n\n  const source = txtRecordOptions.get('authSource') ?? undefined;\n  const replicaSet = txtRecordOptions.get('replicaSet') ?? undefined;\n  const loadBalanced = txtRecordOptions.get('loadBalanced') ?? undefined;\n\n  if (\n    !options.userSpecifiedAuthSource &&\n    source &&\n    options.credentials &&\n    !AUTH_MECHS_AUTH_SRC_EXTERNAL.has(options.credentials.mechanism)\n  ) {\n    options.credentials = MongoCredentials.merge(options.credentials, { source });\n  }","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/connection_string.ts#L105-L141","documentation":"The only TXT record options MongoDB+SRV permits are the keys in VALID_TXT_RECORDS (authSource, replicaSet, loadBalanced). If a TXT record carries any other key, the driver rejects it to avoid silently ignored or ambiguous configuration. This enforces the cross-driver SRV specification.","triggerScenarios":"A mongodb+srv:// URI whose DNS TXT record contains key=value pairs outside the allowed set (e.g. 'tls=true', 'appName=foo', 'connectTimeoutMS=5000').","commonSituations":"An operator tries to set TLS, timeouts, or appName via DNS TXT instead of the URI query string, not realizing SRV TXT only allows three keys.","solutions":["Check the TXT record content: dig TXT <srvHost>.","Remove any key that is not authSource, replicaSet, or loadBalanced from the TXT record.","Move those options into the connection string query string (e.g. 'mongodb+srv://host/db?tls=true&appName=foo')."],"exampleFix":"// DNS TXT before: \"authSource=admin&tls=true\"\n// DNS TXT after:   \"authSource=admin\"\n// URI:             mongodb+srv://host/db?tls=true","handlingStrategy":"validation","validationCode":"import { promises as dns } from 'dns';\n\nconst VALID = ['authSource', 'replicaSet', 'loadBalanced'];\n\nasync function validateTxtKeys(srvHost: string) {\n  const records = await dns.resolveTxt(srvHost);\n  if (records.length === 0) return;\n  const params = new URLSearchParams(records[0].join(''));\n  for (const key of params.keys()) {\n    if (!VALID.includes(key)) {\n      throw new Error(`Invalid TXT key '${key}'. Allowed: ${VALID.join(', ')}`);\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep SRV TXT record authoring in a reviewed config file (Terraform/CloudFormation), not a manual DNS UI.","Document the three allowed keys for whoever owns DNS."],"tags":["dns","connection-string","srv","txt-record","validation"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}