denoland/deno · error · TypeError
ERR_TLS_INVALID_PROTOCOL_VERSION
ERR_TLS_INVALID_PROTOCOL_VERSION
Error message
${options.minVersion} is not a valid minVersion TLS protocol version What it means
When secureProtocol is absent, getProtocolRange validates minVersion against the kValidVersions set; a value not in the set throws ERR_TLS_INVALID_PROTOCOL_VERSION reporting that the value is not a valid minVersion. Valid strings are the exact forms 'TLSv1.3', 'TLSv1.2', 'TLSv1.1', 'TLSv1' - other spellings, numbers, or casing fail.
Source
Thrown at ext/node/polyfills/_tls_common.ts:329
}
if (
options.secureProtocol === "SSLv3_method" ||
options.secureProtocol === "SSLv3_client_method" ||
options.secureProtocol === "SSLv3_server_method"
) {
throw new ERR_TLS_INVALID_PROTOCOL_METHOD("SSLv3 methods disabled");
}
throw new ERR_TLS_INVALID_PROTOCOL_METHOD(
`Unknown method: ${options.secureProtocol}`,
);
}
minVersion = range[0];
maxVersion = range[1];
} else {
if (options.minVersion) {
if (!SetPrototypeHas(kValidVersions, options.minVersion)) {
throw new ERR_TLS_INVALID_PROTOCOL_VERSION(
options.minVersion,
"minVersion",
);
}
minVersion = options.minVersion;
}
if (options.maxVersion) {
if (!SetPrototypeHas(kValidVersions, options.maxVersion)) {
throw new ERR_TLS_INVALID_PROTOCOL_VERSION(
options.maxVersion,
"maxVersion",
);
}
maxVersion = options.maxVersion;
}
}
return { minVersion, maxVersion };View on GitHub (pinned to 89f33cbef2)
Solutions
- Use the exact strings: 'TLSv1.3' | 'TLSv1.2' | 'TLSv1.1' | 'TLSv1'
- Validate against a whitelist before creating the TLS socket/server
- Trim and canonicalize values coming from config/env
- Omit minVersion to accept the library default rather than guessing spellings
Example fix
// before
new tls.TLSSocket(s, { minVersion: 'tls1.2' }); // invalid string
// after
new tls.TLSSocket(s, { minVersion: 'TLSv1.2' }); Defensive patterns
Strategy: validation
Validate before calling
const VALID_VERSIONS = ['TLSv1.3', 'TLSv1.2', 'TLSv1.1', 'TLSv1'];
if (opts.minVersion && !VALID_VERSIONS.includes(opts.minVersion)) {
delete opts.minVersion; // or throw with a clear config error
}
if (opts.maxVersion && !VALID_VERSIONS.includes(opts.maxVersion)) {
delete opts.maxVersion;
} Type guard
function isTlsVersion(v) {
return v === 'TLSv1.3' || v === 'TLSv1.2' || v === 'TLSv1.1' || v === 'TLSv1';
} Try / catch
try {
sock = new tls.TLSSocket(s, opts);
} catch (e) {
if (e.code === 'ERR_TLS_INVALID_PROTOCOL_VERSION' && /minVersion/.test(e.message)) {
const { minVersion, ...rest } = opts;
sock = new tls.TLSSocket(s, rest);
} else throw e;
} Prevention
- Centralize the exact version strings in one constants module
- Trim and validate env/YAML-sourced version strings at load time
- Omit minVersion when the library default is acceptable
When it happens
Trigger: minVersion: 'tls1.2' (lowercase), 'TLSv1.4' (nonexistent), 'TLS1_2' (wrong shape), 1.2 as a number, or 'SSLv3' - none of which are in kValidVersions.
Common situations: Format confusion with OpenSSL/browser cipher config ('TLSv1.2' vs 'tlsv1.2' vs '1.2'); values read from env vars or YAML without normalization; copy-paste from platform-specific docs.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- ERR_TLS_PROTOCOL_VERSION_CONFLICT
- ERR_INVALID_ARG_TYPE
- Cannot create cron job, a unique name is required: received
- Cannot create cron job, a schedule is required: received 'un
- Invalid value for 'proxy.transport' option: ${JSONStringify(
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/33e8b9688d8660de.
Report an issue: GitHub.