{"record":{"id":"31d50b6106be0643","repo":"mongodb/node-mongodb-native","slug":"server-record-does-not-share-hostname-with-parent","errorCode":null,"errorMessage":"Server record does not share hostname with parent URI","messagePattern":"Server record does not share hostname with parent URI","errorType":"exception","errorClass":"MongoAPIError","httpStatus":null,"severity":"error","filePath":"src/utils.ts","lineNumber":1186,"sourceCode":"  //   will not satisfy an addressDomain that endsWith '.fake-trusted.site'\n  const addressDomain = `.${normalizedAddress.replace(allCharacterBeforeFirstDot, '')}`;\n  let srvHostDomain = srvIsLessThanThreeParts\n    ? normalizedSrvHost\n    : `.${normalizedSrvHost.replace(allCharacterBeforeFirstDot, '')}`;\n\n  if (!srvHostDomain.startsWith('.')) {\n    srvHostDomain = '.' + srvHostDomain;\n  }\n  if (\n    srvIsLessThanThreeParts &&\n    normalizedAddress.split('.').length <= normalizedSrvHost.split('.').length\n  ) {\n    throw new MongoAPIError(\n      'Server record does not have at least one more domain level than parent URI'\n    );\n  }\n  if (!addressDomain.endsWith(srvHostDomain)) {\n    throw new MongoAPIError('Server record does not share hostname with parent URI');\n  }\n}\n\n/**\n * Perform a get request that returns status and body.\n * @internal\n */\nexport function get(\n  url: URL | string,\n  options: http.RequestOptions = {}\n): Promise<{ body: string; status: number | undefined }> {\n  return new Promise((resolve, reject) => {\n    /* eslint-disable prefer-const */\n    let timeoutId: NodeJS.Timeout;\n    const request = http\n      .get(url, options, response => {\n        response.setEncoding('utf8');\n        let body = '';","sourceCodeStart":1168,"sourceCodeEnd":1204,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/utils.ts#L1168-L1204","documentation":"Thrown by checkParentDomainMatch() when a resolved SRV record address's domain does not end with the srvHost's domain. The driver enforces that every SRV-advertised host be a subdomain of the srvHost from the connection string; a mismatch implies DNS hijacking or misconfiguration. Raised as MongoAPIError.","triggerScenarios":"Connecting via mongodb+srv:// where a DNS SRV response returns a hostname that is not under the srvHost domain (e.g. srvHost is cluster.example.com but an SRV record points to evil.attacker.com). This is the core SRV hostname-verification guard.","commonSituations":"Compromised or misconfigured DNS server returning out-of-domain addresses. Using a custom SRV hostname whose records were edited to point at an unrelated host. Internal DNS changes that forget to update SRV targets.","solutions":["Correct the DNS SRV records so all targets are subdomains of the srvHost in the connection string.","Verify with 'dig SRV _mongodb._tcp.<srvHost>' that every returned target ends with the srvHost domain.","If unintended, investigate possible DNS tampering or a stale/cached record."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await client.connect();\n} catch (e) {\n  if (e instanceof MongoAPIError && /does not share hostname/.test(e.message)) {\n    // investigate DNS: SRV records must be subdomains of the srvHost\n  } else throw e;\n}","preventionTips":["Ensure every SRV record target is a subdomain of the srvHost in the connection string.","Audit DNS records after any infrastructure migration.","Investigate unexpected records as possible DNS tampering."],"tags":["dns","srv","security","connection-string"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}