denoland/deno · error · TypeError
ERR_INVALID_URL
ERR_INVALID_URL
Error message
Invalid URL: ${urlStr} What it means
getURLOrigin parses a string with new URL(urlStr) and takes .origin; any parse failure is rethrown as ERR_INVALID_URL. It is used when submitting ORIGIN frames (http2session.origin(...origins)), alt-svc frames (http2session.altsvc(alt, origin)), and when computing session.originSet, so HTTP/2 metadata frames never carry a malformed origin.
Source
Thrown at ext/node/polyfills/http2.ts:307
}
function debugSession(sessionType, message, ...args) {
ReflectApply(debug, null, [
"Http2Session %s: " + message,
sessionName(sessionType),
...new SafeArrayIterator(args),
]);
}
function debugSessionObj(session, message, ...args) {
debugSession(session[kType], message, ...new SafeArrayIterator(args));
}
function getURLOrigin(urlStr) {
try {
return new URL(urlStr).origin;
} catch {
throw new ERR_INVALID_URL(urlStr);
}
}
function perfNow() {
return webPerformance.now();
}
function emitSessionPerfEntry(session) {
if (session[kPerfEmitted]) return;
session[kPerfEmitted] = true;
const stats = session[kPerfStats];
if (!stats) return;
const startTime = stats.startTime;
const duration = perfNow() - startTime;
const handle = session[kHandle];
const framesReceived = handle && typeof handle.framesReceived === "function"
? handle.framesReceived()View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Pass full absolute URLs with scheme and host: session.origin('https://example.com:8443')
- Pass URL objects instead of strings — the implementation uses their .origin property and skips parsing
- Pre-validate with new URL(str) (or URL.canParse(str)) before calling origin() or altsvc()
Example fix
// before
session.origin('example.com'); // throws ERR_INVALID_URL
// after
session.origin(new URL('https://example.com')); // uses .origin, no parse risk Defensive patterns
Strategy: validation
Validate before calling
const parseableOrigin = (s: string): boolean => {
try {
return new URL(s).origin !== 'null';
} catch {
return false;
}
};
if (!parseableOrigin(originStr)) throw new Error(`bad origin: ${originStr}`);
session.origin(originStr); Type guard
const isAbsoluteHttpUrl = (v: string): boolean => URL.canParse(v) && /^https?:$/.test(new URL(v).protocol);
Try / catch
try {
session.origin(originStr);
} catch (err) {
if ((err as NodeJS.ErrnoException).code === 'ERR_INVALID_URL') {
// drop or fix the malformed origin, then continue
} else throw err;
} Prevention
- Pass URL objects to session.origin/altsvc so parsing happens once, up front
- Store full absolute origins (scheme + host + port) in config, not bare hostnames
- Normalize with new URL(...).origin at config-load time
When it happens
Trigger: session.origin('example.com') (no scheme); session.altsvc('h2=":8443"', 'https://') (empty host); origins built by concatenation that yield strings with spaces or invalid characters; passing a URL string that is not absolute (no protocol).
Common situations: Config files that store bare hostnames and are fed to session.origin/altsvc without normalization; building origins from user input via template strings; non-ASCII or unserialized punycode hostnames; porting code that assumed lenient parsing.
Related errors
- ERR_HTTP2_INVALID_ORIGIN
- ERR_HTTP2_ALTSVC_INVALID_ORIGIN
- ERR_HTTP2_ORIGIN_LENGTH
- ERR_HTTP2_NO_SOCKET_MANIPULATION
- ERR_HTTP2_SOCKET_UNBOUND
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/8fc1e5702654b114.
Report an issue: GitHub.