copy/v86 · warning
Unknown port for localhost: "%s"
Error message
Unknown port for localhost: "%s"
What it means
v86's fetch-based networking maps guest HTTP requests to the special hostname '<port>.external' back to real localhost:<port> on the host machine. In on_data_http (src/browser/fetch_network.js:193), when no CORS proxy is configured and the target hostname matches /^\d+\.external$/, the numeric label is parsed as a local port; if parsing fails, the number is 0, or it exceeds 65535, the library logs this warning and answers the guest's request with HTTP 400 Bad Request instead of proxying it.
Source
Thrown at src/browser/fetch_network.js:193
return;
}
if(header.key.toLowerCase() === "host") target.host = header.value;
else req_headers.append(header.key, header.value);
}
if(!this.net.cors_proxy && /^\d+\.external$/.test(target.hostname))
{
dbg_log("Request to localhost: " + target.href, LOG_FETCH);
const localport = parseInt(target.hostname.split(".")[0], 10);
if(!isNaN(localport) && localport > 0 && localport < 65536)
{
target.protocol = "http:";
target.hostname = "localhost";
target.port = localport.toString(10);
}
else
{
console.warn('Unknown port for localhost: "%s"', target.href);
this.net.respond_text_and_close(this, 400, "Bad Request", `Unknown port for localhost: ${target.href}`);
return;
}
}
dbg_log("HTTP Dispatch: " + target.href, LOG_FETCH);
this.name = target.href;
const opts = {
method: first_line[0],
headers: req_headers,
};
const fetch_url = this.net.cors_proxy
? this.net.cors_proxy + encodeURIComponent(target.href)
: target.href;
if(["put", "post"].indexOf(opts.method.toLowerCase()) !== -1)View on GitHub (pinned to 180830d539)
Solutions
- Fix the guest-side URL so the hostname is exactly '<port>.external' with port in 1-65535 (e.g. '8080.external'), not e.g. 'localhost.external' or '99999.external'
- Check the guest application's proxy/server configuration or environment variable that supplies the port, ensuring it is numeric and in range
- Verify no cors_proxy option was intended: if you route through a CORS proxy, .external mapping is skipped entirely, so set FetchNetworkAdapter's cors_proxy if you want normal proxying instead
- Inspect the logged target.href in the warning to see the exact malformed hostname the guest sent and trace which guest process produced it
Example fix
// before (inside guest OS) curl http://myserver.external/api // after curl http://8080.external/api # 8080 = port of the host service
Defensive patterns
Strategy: validation
Validate before calling
// repeat: guard guest-side URLs before dispatch
if(!/^\d+\.external$/.test(host)) throw new Error('guest host must be <port>.external');
const port = parseInt(host.split('.')[0], 10);
if(!(port > 0 && port < 65536)) throw new Error('port out of range in ' + host); Try / catch
// The warning surfaces as HTTP 400 from the proxy — handle on the guest side
const resp = await guestFetch(url);
if(resp.status === 400)
{
const body = await resp.text();
if(body.startsWith('Unknown port for localhost'))
throw new Error('malformed .external hostname: ' + body);
} Prevention
- Format host service URLs inside the guest as '<port>.external' strictly
- Validate ports are 1-65535 before substituting into hostnames
- Enable v86 debug logging (LOG_FETCH) in dev to trace guest HTTP dispatches
- Do not mix cors_proxy and .external conventions — pick one mapping strategy
When it happens
Trigger: A program inside the emulated guest OS sends an HTTP request to a hostname like '99999.external', '0.external', 'abc.external', or any '*.external' name whose first label is not a valid port number (1-65535), while running without a cors_proxy configured.
Common situations: Guest software with hardcoded or misconfigured proxy/host settings producing malformed .external hostnames; tools that substitute the port into the wrong position of the hostname; port 0 from an unset environment variable or failed port lookup inside the guest; a non-numeric value leaking into the hostname slot.
Related errors
- stream capacity overflow in GrowableRingbuffer.write(), pack
- pool of dynamic TCP port numbers exhausted, connection abort
- Got a DATA packet but stream not registered. ID:
- The request contains an invalid header: "%s"
- Web browser doesn't support Web Audio API
AI-assisted analysis of copy/v86@180830d539 (2026-08-31).
Data as JSON: /api/errors/94a527dd69b79af9.
Report an issue: GitHub.