denoland/deno · error
Can't convert url ("{}") to filename.
Error message
Can't convert url ("{}") to filename. What it means
url_to_filename() maps a Url to a cache filename by first splitting it into [scheme, host] parts via base_url_to_filename_parts (libs/cache_dir/common.rs:13). That helper only understands the http, https, data and blob schemes; every other scheme logs "Don't know how to create cache name for scheme" and returns None, which url_to_filename converts into this InvalidInput io::Error echoing the offending URL. It exists because arbitrary schemes (file:, npm:, custom protocols) cannot be mapped deterministically into the cache layout this library maintains.
Source
Thrown at libs/cache_dir/cache.rs:99
actual,
}))
} else {
Ok(())
}
}
}
/// Turn provided `url` into a hashed filename.
/// URLs can contain a lot of characters that cannot be used
/// in filenames (like "?", "#", ":"), so in order to cache
/// them properly they are deterministically hashed into ASCII
/// strings.
pub fn url_to_filename(url: &Url) -> std::io::Result<PathBuf> {
// Replaces port part with a special string token (because
// ":" cannot be used in filename on some platforms).
// Ex: $DENO_DIR/remote/https/deno.land/
let Some(cache_parts) = base_url_to_filename_parts(url, "_PORT") else {
return Err(std::io::Error::new(
ErrorKind::InvalidInput,
format!("Can't convert url (\"{}\") to filename.", url),
));
};
let rest_str = if let Some(query) = url.query() {
let mut rest_str =
String::with_capacity(url.path().len() + 1 + query.len());
rest_str.push_str(url.path());
rest_str.push('?');
rest_str.push_str(query);
Cow::Owned(rest_str)
} else {
Cow::Borrowed(url.path())
};
// NOTE: fragment is omitted on purpose - it's not taken into
// account when caching - it denotes parts of webpage, whichView on GitHub (pinned to 9ad36f7a2c)
Solutions
- Inspect the URL printed in the message and fix the caller to pass an http/https (or data/blob) URL — this is almost always a caller bug, not a cache bug.
- If you must handle other schemes, branch on url.scheme() before calling url_to_filename and build your own filename for the unsupported schemes instead of relying on the cache layout.
- Check where the URL originates (module loader, CLI arg, config file) and make sure a file path or bare specifier was not coerced into a Url with an unexpected scheme.
Example fix
// before
let path = url_to_filename(&Url::parse("file:///mod.ts")?)?; // Err: Can't convert url ("file:///mod.ts") to filename.
// after
let url = Url::parse("file:///mod.ts")?;
let path = match url.scheme() {
"http" | "https" | "data" | "blob" => url_to_filename(&url)?,
other => {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
format!("unsupported cache scheme: {other}"),
))
}
}; Defensive patterns
Strategy: validation
Validate before calling
fn is_cacheable_url(url: &url::Url) -> bool {
matches!(url.scheme(), "http" | "https" | "data" | "blob")
}
// before caching:
if !is_cacheable_url(&url) {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
format!("cannot cache non-remote url: {url}"),
));
}
let path = url_to_filename(&url)?; Try / catch
match url_to_filename(&url) {
Ok(path) => { /* use path */ }
Err(err) if err.kind() == std::io::ErrorKind::InvalidInput => {
// unsupported scheme (not http/https/data/blob) — handle locally or skip caching
}
Err(err) => return Err(err),
} Prevention
- Normalize specifiers at your system's boundary: resolve file:/bare/custom specifiers to concrete paths before anything reaches the remote cache.
- Keep a whitelist of schemes your loader supports and validate URLs against it before calling cache APIs.
- Log the scheme (not just the URL) when caching fails so scheme regressions are obvious in CI.
When it happens
Trigger: Calling url_to_filename() directly, or indirectly through HttpCache operations (get/put/remove with cache keys built from URLs), with a URL whose scheme is not http/https/data/blob — e.g. Url::parse("file:///mod.ts"), "npm:pkg", "node:fs", or a custom protocol URL.
Common situations: Custom module loaders that produce non-HTTP specifiers and feed them into the HTTP cache; passing a file path or package specifier where a remote URL is required; newer code paths routing URLs of previously-unseen schemes into the cache; tests using example/spec URLs like "example:foo".
Related errors
- Can't convert url ("{}") to filename.
- ERR_INVALID_URL_SCHEME
- ERR_INVALID_URL
- ERR_HTTP2_PAYLOAD_FORBIDDEN
- ERR_INVALID_URL_SCHEME
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/fd4daa57a53ed9a6.
Report an issue: GitHub.