vi/websocat · error
Request URI doesn't match --restrict-uri parameter
Error message
Request URI doesn't match --restrict-uri parameter
What it means
Raised during WebSocket upgrade in ws_upgrade_peer when the request URI does not equal the --restrict-uri parameter value. The check requires the request's absolute path to match restrict_uri exactly (AbsolutePath == restrict_uri); on failure the server rejects the handshake, logs a warning, and returns simple_err wrapped as a WebSocketError::IoError. This enforces that the server only accepts upgrades at one specific path.
Solutions
- Connect to the exact path given in --restrict-uri (e.g. ws://host:8080/echo when --restrict-uri=/echo), including no trailing slash.
- If the path is intentional, update --restrict-uri on the server to match it and restart.
- Remove the --restrict-uri option if any path should be accepted.
- Check reverse-proxy configuration for path rewrites/strips that alter the URI before it reaches the server.
Example fix
// before: server started with --restrict-uri=/echo but client hits another path
const ws = new WebSocket("ws://host:8080/");
// after
const ws = new WebSocket("ws://host:8080/echo"); Defensive patterns
Strategy: validation
Validate before calling
// Client-side pre-check before connecting (JS)
const restrictUri = "/echo"; // mirrors server --restrict-uri
const path = new URL(wsUrl).pathname;
if (path !== restrictUri) throw new Error(`path ${path} does not match --restrict-uri ${restrictUri}`); Try / catch
ws.addEventListener("error", () => {
// rejected handshake: request URI did not match --restrict-uri
console.error("Upgrade rejected: URI does not match --restrict-uri");
}); Prevention
- Derive the client URL from the same config value used for --restrict-uri.
- Watch for proxies that rewrite or strip the request path.
- Match exact path text (no trailing slash differences).
When it happens
Trigger: A client sends a WebSocket upgrade whose request path differs from --restrict-uri (e.g. server started with --restrict-uri=/echo but the client connects to / or /other), including trailing-slash or query-string/path-case differences that break exact comparison.
Common situations: Client URL path edited or defaulted to '/' while --restrict-uri is set; reverse proxy rewriting the path before it reaches the server; mismatch between a documented endpoint and the restrict-uri flag; trailing slash ('/echo/' vs '/echo').
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
AI-assisted analysis of vi/websocat@3a3574cd2f (2026-09-12).
Data as JSON: /api/errors/f7603d60fe13ad15.
Report an issue: GitHub.
Appendix: source
Thrown at src/ws_server_peer.rs:237
warn!("Header {} value contains invalid UTF-8", q);
}
} else {
warn!("No request header {}, so no envvar H_{}", q, q);
}
}
},
L2rUser::ReadFrom(_) => {},
}
if let Some(ref restrict_uri) = *restrict_uri {
let check_passed = matches!(x.request.subject.1, AbsolutePath(ref x) if x == restrict_uri);
if !check_passed {
return Box::new(
x.reject()
.and_then(|_| {
warn!("Incoming request URI doesn't match the --restrict-uri value");
::futures::future::err(crate::util::simple_err(
"Request URI doesn't match --restrict-uri parameter"
.to_string(),
))
})
.map_err(|e| websocket::WebSocketError::IoError(io_other_error(e))),
)
as Box<dyn Future<Item = Peer, Error = websocket::WebSocketError>>;
}
};
Box::new(x.accept_with_limits(opts.max_ws_frame_length, opts.max_ws_message_length).map(move |(y, headers)| {
debug!("{:?}", headers);
info!("Upgraded");
let close_on_shutdown = !opts.websocket_dont_close;
super::ws_peer::finish_building_ws_peer(&opts, y, close_on_shutdown, None)
})) as Box<dyn Future<Item = Peer, Error = websocket::WebSocketError>>
},
);
let step4 = step3.map_err(box_up_err);View on GitHub (pinned to 3a3574cd2f)