redis/node-redis · error · TypeError
tls socket option is set to ${options.socket.tls} which is m
Error message
tls socket option is set to ${options.socket.tls} which is mismatch with protocol or the URL ${options.url} passed What it means
During parseOptions, when both `options.url` and `options.socket` are provided, the client checks that any explicit `socket.tls` agrees with the URL's scheme (rediss:// => tls true, redis:// => tls false). A mismatch means the developer asked for two contradictory things (e.g. a rediss:// URL but socket.tls=false, or redis:// with socket.tls=true), which would produce a confusing TLS handshake failure later — so it fails fast with a TypeError showing both values.
Source
Thrown at packages/client/lib/client/index.ts:457
};
}
static create<
M extends RedisModules = {},
F extends RedisFunctions = {},
S extends RedisScripts = {},
RESP extends RespVersions = 3,
TYPE_MAPPING extends TypeMapping = {}
>(this: void, options?: RedisClientOptions<M, F, S, RESP, TYPE_MAPPING>) {
return RedisClient.factory(options)(options);
}
static parseOptions<O extends AnyRedisClientOptions>(options: O): O {
if (options?.url) {
const parsed = RedisClient.parseURL(options.url);
if (options.socket) {
if (options.socket.tls !== undefined && options.socket.tls !== parsed.socket.tls) {
throw new TypeError(`tls socket option is set to ${options.socket.tls} which is mismatch with protocol or the URL ${options.url} passed`)
}
parsed.socket = Object.assign(options.socket, parsed.socket);
}
Object.assign(options, parsed);
}
return options;
}
static parseURL(url: string): AnyRedisClientOptions & {
socket: Exclude<AnyRedisClientOptions['socket'], undefined> & {
tls: boolean
}
} {
// unix:// URIs use a non-special scheme; WHATWG URL refuses to parse an
// authority (e.g. `user:pass@`) without a host, so handle it separately.
if (url.startsWith('unix:')) {
return RedisClient.#parseUnixURL(url);View on GitHub (pinned to bb5beb5657)
Solutions
- Make TLS consistent: use rediss:// together with socket.tls omitted (it is derived from the URL), or set socket.tls to match the scheme.
- Prefer specifying TLS via the URL scheme only and drop the explicit socket.tls to avoid the conflict.
- Centralize connection config so the URL scheme and socket.tls cannot drift apart.
Example fix
// before
createClient({ url: 'rediss://host:6379', socket: { tls: false } });
// after
createClient({ url: 'rediss://host:6379' }); Defensive patterns
Strategy: validation
Validate before calling
function resolveRedisOptions(raw) {
if (raw.url && raw.socket?.tls !== undefined) {
const schemeTls = raw.url.startsWith('rediss://');
if (raw.socket.tls !== schemeTls) {
throw new TypeError('socket.tls conflicts with the URL scheme');
}
}
return raw;
} Prevention
- Specify TLS via the URL scheme only (rediss://) and omit socket.tls.
- Centralize connection config so scheme and socket.tls cannot drift.
- When migrating redis:// to rediss://, remove explicit socket.tls overrides.
When it happens
Trigger: `createClient({ url: 'rediss://host:6379', socket: { tls: false } })`; `createClient({ url: 'redis://host:6379', socket: { tls: true } })`; merging a tls:false default socket config with a rediss:// URL from env.
Common situations: Layered config (base config sets socket.tls, env provides the URL) where the two disagree; copy-paste from an example that hard-coded socket.tls; migrating from redis:// to rediss:// without removing an explicit socket.tls override.
Related errors
- Invalid protocol
- Invalid pathname
- Invalid unix URL
- Invalid db query parameter
- expirationRefreshRatio must be less than or equal to 1
AI-assisted analysis of redis/node-redis@bb5beb5657 (2026-08-03).
Data as JSON: /data/errors/74b26fbee5675206.json.
Report an issue: GitHub.