copy/v86 · warning
Unknown port for localhost
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.
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
- Got a DATA packet but stream not registered. ID:
- pool of dynamic TCP port numbers exhausted, connection…
- stream capacity overflow in GrowableRingbuffer.write()…
- The request contains an invalid header
- Warning: Unknown option 'state'. Did you mean…
AI-assisted analysis of copy/v86@180830d539 (2026-08-31).
Data as JSON: /api/errors/94a527dd69b79af9.
Report an issue: GitHub.
Appendix: 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)