{"record":{"id":"1b9c80cce3f99981","repo":"mongodb/node-mongodb-native","slug":"cannot-have-empty-uri-params-in-dns-txt-record","errorCode":null,"errorMessage":"Cannot have empty URI params in DNS TXT Record","messagePattern":"Cannot have empty URI params in DNS TXT Record","errorType":"exception","errorClass":"MongoParseError","httpStatus":null,"severity":"error","filePath":"src/connection_string.ts","lineNumber":127,"sourceCode":"  } 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  }\n\n  if (!options.userSpecifiedReplicaSet && replicaSet) {\n    options.replicaSet = replicaSet;\n  }","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/connection_string.ts#L109-L145","documentation":"Each allowed TXT record option must have a value. The driver iterates VALID_TXT_RECORDS and rejects any option whose value is the empty string, because an optionless key in a TXT record is ambiguous and almost always a DNS formatting mistake.","triggerScenarios":"A DNS TXT record containing a trailing 'authSource=' with no value, e.g. 'authSource=admin&replicaSet=' or 'authSource='. Produced while parsing TXT record options in resolveSRVRecord.","commonSituations":"Operator deletes a TXT value but leaves the key, or copy-pastes a malformed TXT string into the DNS management UI.","solutions":["Inspect the TXT record: dig TXT <srvHost>.","Either supply a value for the empty key or remove the key entirely.","Reload the connection after DNS TTL expires or flush local DNS cache."],"exampleFix":"// DNS TXT before: \"authSource=admin&loadBalanced=\"\n// DNS TXT after:   \"authSource=admin&loadBalanced=true\"","handlingStrategy":"validation","validationCode":"import { promises as dns } from 'dns';\n\nasync function validateTxtValues(srvHost: string) {\n  const records = await dns.resolveTxt(srvHost);\n  if (!records.length) return;\n  const params = new URLSearchParams(records[0].join(''));\n  for (const [k, v] of params.entries()) {\n    if (v === '') throw new Error(`TXT option '${k}' has empty value`);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate TXT content in CI with a DNS check stage.","Avoid hand-editing TXT strings; generate them."],"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"}