mongodb/node-mongodb-native · error · MongoAPIError

Invalid CANONICALIZE_HOST_NAME value

Error message

Invalid CANONICALIZE_HOST_NAME value: ${canonicalization}

What it means

Thrown by MongoCredentials.validate() when CANONICALIZE_HOST_NAME has a value not in the allowed set. Allowed values are: true ('on'), false ('off'), 'none', 'forward', 'forwardAndReverse'. This property controls GSSAPI/Kerberos hostname canonicalization and an unrecognized value is rejected before any auth attempt.

Solutions

  1. Use one of: true, false, 'none', 'forward', 'forwardAndReverse'.
  2. If passing via connection string, use the canonical lowercase token (e.g. CANONICALIZE_HOST_NAME:forward).
  3. In JS code, pass the actual boolean true/false, not the strings 'true'/'false'.

Example fix

// before
mechanismProperties: { CANONICALIZE_HOST_NAME: 'yes' }
// after
mechanismProperties: { CANONICALIZE_HOST_NAME: 'forward' }
Defensive patterns

Strategy: type-guard

Validate before calling

const ALLOWED = [true,false,'none','forward','forwardAndReverse'];
function assertCanonicalize(v) {
  if (!ALLOWED.includes(v)) throw new Error('Invalid CANONICALIZE_HOST_NAME');
}

Type guard

function isCanonicalizeValue(v): v is boolean|'none'|'forward'|'forwardAndReverse' {
  return [true,false,'none','forward','forwardAndReverse'].includes(v);
}

Prevention

When it happens

Trigger: Setting authMechanismProperties.CANONICALIZE_HOST_NAME to a string or value outside the allowed set while using GSSAPI (or any mechanism, since the check runs for all). Fires at validate() line 274.

Common situations: Typing 'true'/'false' as strings in code (string 'true' is not boolean true). Using values like 'yes'/'no'/'both'. Confusing the boolean and string forms of the option.

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11). Data as JSON: /api/errors/bdcbcf69852b599a. Report an issue: GitHub.

Appendix: source

Thrown at src/cmap/auth/mongo_credentials.ts:275

    }

    if (this.mechanism === AuthMechanism.MONGODB_PLAIN && this.source == null) {
      // TODO(NODE-3485): Replace this with a MongoAuthValidationError
      throw new MongoAPIError('PLAIN Authentication Mechanism needs an auth source');
    }

    if (this.mechanism === AuthMechanism.MONGODB_X509 && this.password != null) {
      if (this.password === '') {
        Reflect.set(this, 'password', undefined);
        return;
      }
      // TODO(NODE-3485): Replace this with a MongoAuthValidationError
      throw new MongoAPIError(`Password not allowed for mechanism MONGODB-X509`);
    }

    const canonicalization = this.mechanismProperties.CANONICALIZE_HOST_NAME ?? false;
    if (!Object.values(GSSAPICanonicalizationValue).includes(canonicalization)) {
      throw new MongoAPIError(`Invalid CANONICALIZE_HOST_NAME value: ${canonicalization}`);
    }
  }

  static merge(
    creds: MongoCredentials | undefined,
    options: Partial<MongoCredentialsOptions>
  ): MongoCredentials {
    return new MongoCredentials({
      username: options.username ?? creds?.username ?? '',
      password: options.password ?? creds?.password ?? '',
      mechanism: options.mechanism ?? creds?.mechanism ?? AuthMechanism.MONGODB_DEFAULT,
      mechanismProperties: options.mechanismProperties ?? creds?.mechanismProperties ?? {},
      source: options.source ?? options.db ?? creds?.source ?? 'admin'
    });
  }
}

View on GitHub (pinned to dce7939f86)