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
- Correct the SRV records so every target hostname ends with the srvHost domain (e.g. host.cluster.example.com under cluster.example.com).
- If you intentionally host MongoDB outside the srvHost domain, stop using mongodb+srv:// and use a plain mongodb:// seedlist instead.
- Verify with `dig SRV _mongodb._tcp.<srvHost>` that all returned targets are subdomains of the parent.
- 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
- Run `dig SRV _mongodb._tcp.<srvHost>` and confirm each target is a subdomain of the parent.
- Watch for CNAME flattening or DNS proxies that strip the parent domain.
- When hosting MongoDB outside the srvHost domain, use mongodb:// seedlist instead of mongodb+srv://.
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
- Server record does not have at least one more domain level t
- Option "srvHost" must not be empty
- No addresses found at host
- Multiple text records not allowed
- Text record may only set any of: ${VALID_TXT_RECORDS.join(',
AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04).
Data as JSON: /data/errors/31d50b6106be0643.json.
Report an issue: GitHub.