mongodb/node-mongodb-native · error · MongoAPIError

Server record does not share hostname with parent URI

Error message

Server record does not share hostname with parent URI

What it means

Thrown by checkParentDomainMatch() when a resolved SRV/TXT host's domain does not end with the srvHost's domain. This is the primary hostname-is-a-subdomain guard that prevents a compromised DNS server from redirecting the MongoDB client to attacker-controlled hosts, and is part of the cross-driver SRV security contract. It surfaces as a MongoAPIError and is checked from srv_polling.ts (runtime SRV polling) and connection_string.ts (initial TXT lookup).

Source

Thrown at src/utils.ts:1186

  //   will not satisfy an addressDomain that endsWith '.fake-trusted.site'
  const addressDomain = `.${normalizedAddress.replace(allCharacterBeforeFirstDot, '')}`;
  let srvHostDomain = srvIsLessThanThreeParts
    ? normalizedSrvHost
    : `.${normalizedSrvHost.replace(allCharacterBeforeFirstDot, '')}`;

  if (!srvHostDomain.startsWith('.')) {
    srvHostDomain = '.' + srvHostDomain;
  }
  if (
    srvIsLessThanThreeParts &&
    normalizedAddress.split('.').length <= normalizedSrvHost.split('.').length
  ) {
    throw new MongoAPIError(
      'Server record does not have at least one more domain level than parent URI'
    );
  }
  if (!addressDomain.endsWith(srvHostDomain)) {
    throw new MongoAPIError('Server record does not share hostname with parent URI');
  }
}

/**
 * Perform a get request that returns status and body.
 * @internal
 */
export function get(
  url: URL | string,
  options: http.RequestOptions = {}
): Promise<{ body: string; status: number | undefined }> {
  return new Promise((resolve, reject) => {
    /* eslint-disable prefer-const */
    let timeoutId: NodeJS.Timeout;
    const request = http
      .get(url, options, response => {
        response.setEncoding('utf8');
        let body = '';

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Correct the SRV records so every target hostname ends with the srvHost domain (e.g. host.cluster.example.com under cluster.example.com).
  2. If you intentionally host MongoDB outside the srvHost domain, stop using mongodb+srv:// and use a plain mongodb:// seedlist instead.
  3. Verify with `dig SRV _mongodb._tcp.<srvHost>` that all returned targets are subdomains of the parent.
  4. Check for CNAME flattening or DNS proxies that rewrite target hostnames.

Example fix

// before (SRV record returns host.not-subdomain.com)
const uri = 'mongodb+srv://cluster.example.com/'; // => MongoAPIError

// after (fix DNS so SRV returns node1.cluster.example.com) OR use seedlist:
const uri = 'mongodb://node1.example.com:27017,node2.example.com:27017/?replicaSet=cluster0';
Defensive patterns

Strategy: try-catch

Validate before calling

function assertSrvTargetIsChild(target: string, srvHost: string): void {
  const t = target.endsWith('.') ? target.slice(0, -1) : target;
  const s = srvHost.endsWith('.') ? srvHost.slice(0, -1) : srvHost;
  if (!t.endsWith('.' + s) && t !== s) {
    throw new Error(`SRV target ${target} is not a subdomain of ${srvHost}`);
  }
}

Try / catch

try {
  await client.connect();
} catch (err) {
  if (err instanceof MongoAPIError && /does not share hostname with parent URI/.test(err.message)) {
    // DNS misconfiguration; switch to a mongodb:// seedlist or fix SRV records
    throw new Error('SRV hostname mismatch; verify DNS records or use a mongodb:// seedlist', { cause: err });
  }
  throw err;
}

Prevention

When it happens

Trigger: An SRV record for cluster.example.com returns a target like host.otherdomain.com that is not a subdomain of example.com; a TXT lookup hostname does not match the parent domain. Triggered at connect time and on every SRV polling cycle.

Common situations: DNS/Atlas misconfiguration publishing out-of-domain SRV targets; CNAME flattening that strips the parent domain; split-horizon DNS returning different records internally; testing setups pointing SRV at localhost or a third-party host.

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04). Data as JSON: /data/errors/31d50b6106be0643.json. Report an issue: GitHub.