sidorares/node-mysql2 · error · TypeError
SSL profile must be an object, instead it's a ${typeof this.
Error message
SSL profile must be an object, instead it's a ${typeof this.ssl} What it means
After resolving the `ssl` config option (a string profile name is looked up and returns an object; any other truthy value is used as-is), mysql2 requires the result to be an object. If `options.ssl` is truthy but not an object (e.g. the boolean `true`, a number, or an array), it throws. mysql2's SSL option must be either a string naming a built-in profile, an object of TLS options, or falsy.
Source
Thrown at lib/connection_config.js:166
? ConnectionConfig.getSSLProfile(options.ssl)
: options.ssl || false;
this.multipleStatements = options.multipleStatements || false;
this.rowsAsArray = options.rowsAsArray || false;
this.namedPlaceholders = options.namedPlaceholders || false;
this.nestTables =
options.nestTables === undefined ? undefined : options.nestTables;
this.typeCast = options.typeCast === undefined ? true : options.typeCast;
this.disableEval = Boolean(options.disableEval);
this.enableCleartextPlugin = Boolean(options.enableCleartextPlugin);
if (this.timezone[0] === ' ') {
// "+" is a url encoded char for space so it
// gets translated to space when giving a
// connection string..
this.timezone = `+${this.timezone.slice(1)}`;
}
if (this.ssl) {
if (typeof this.ssl !== 'object') {
throw new TypeError(
`SSL profile must be an object, instead it's a ${typeof this.ssl}`
);
}
// Default rejectUnauthorized to true
this.ssl.rejectUnauthorized = this.ssl.rejectUnauthorized !== false;
}
this.maxPacketSize = 0;
this.charsetNumber = options.charset
? ConnectionConfig.getCharsetNumber(options.charset)
: options.charsetNumber || Charsets.UTF8MB4_UNICODE_CI;
this.compress = options.compress || false;
this.authPlugins = options.authPlugins;
this.authSwitchHandler = options.authSwitchHandler;
this.clientFlags = ConnectionConfig.mergeFlags(
ConnectionConfig.getDefaultFlags(options),
options.flags || ''
);
// Default connection attributesView on GitHub (pinned to 5ebe8903d6)
Solutions
- Pass an object of TLS options, e.g. `ssl: { rejectUnauthorized: true }`.
- Or pass a string naming a built-in SSL profile if one fits.
- To disable SSL explicitly, set `ssl: false` or omit it.
Example fix
// before
mysql.createConnection({ host, user, password, ssl: true });
// after
mysql.createConnection({ host, user, password, ssl: { rejectUnauthorized: true } }); Defensive patterns
Strategy: validation
Validate before calling
function normalizeSsl(ssl) {
if (ssl === true || (ssl != null && typeof ssl !== 'object' && typeof ssl !== 'string')) {
throw new TypeError('mysql2 ssl must be a string profile name or a TLS options object, not ' + typeof ssl);
}
return ssl;
} Type guard
function isValidSslOption(ssl) {
return ssl == null || typeof ssl === 'string' || (typeof ssl === 'object' && !Array.isArray(ssl));
} Prevention
- Never pass `ssl: true` to mysql2; pass a TLS options object instead.
- Centralise connection-config construction behind a validated factory.
- When migrating from the `mysql` package, replace `ssl: true` with `ssl: {}`.
When it happens
Trigger: Passing `ssl: true` (accepted by some other MySQL libraries like `mysql`/`mysqljs`, but not by mysql2). Or passing a number or array. The value `true` becomes `this.ssl = true` and then fails the `typeof !== 'object'` check.
Common situations: Migrating code from the old `mysql` package which accepts `ssl: true`; setting `ssl: true` after reading a generic Node+MySQL tutorial; environment-driven config that resolves to a boolean.
Related errors
- Unknown SSL profile '${name}'
- Unknown charset '${charset}'
- "user" connection config property must be a string
- "database" connection config property must be a string
AI-assisted analysis of sidorares/node-mysql2@5ebe8903d6 (2026-08-03).
Data as JSON: /data/errors/be58ad1e3cd00a76.json.
Report an issue: GitHub.