zed-industries/zed · error
Unmatched '[' in port forward spec: {spec}
Error message
Unmatched '[' in port forward spec: {spec} What it means
Port-forward specs parsed from ssh command-line options (-L/-R style, e.g. [::1]:8080:localhost:80) are split by split_port_forward_tokens; IPv6 literals are handled as bracket-delimited groups, and an opening '[' with no matching ']' before end-of-string bails, echoing the offending spec.
Source
Thrown at crates/remote/src/transport/ssh.rs:1596
fn parse_port_number(port_str: &str) -> Result<u16> {
port_str
.parse()
.with_context(|| format!("parsing port number: {port_str}"))
}
fn split_port_forward_tokens(spec: &str) -> Result<Vec<String>> {
let mut tokens = Vec::new();
let mut chars = spec.chars().peekable();
while chars.peek().is_some() {
if chars.peek() == Some(&'[') {
chars.next();
let mut bracket_content = String::new();
loop {
match chars.next() {
Some(']') => break,
Some(ch) => bracket_content.push(ch),
None => anyhow::bail!("Unmatched '[' in port forward spec: {spec}"),
}
}
tokens.push(bracket_content);
if chars.peek() == Some(&':') {
chars.next();
}
} else {
let mut token = String::new();
for ch in chars.by_ref() {
if ch == ':' {
break;
}
token.push(ch);
}
tokens.push(token);
}
}
View on GitHub (pinned to f4178619ac)
Solutions
- Balance the brackets: put them around the IPv6 literal only — '[::1]:8080:localhost:80'
- Re-check shell quoting when supplying the spec so no bracket is consumed
- Use plain IPv4 or omit the bind host ('8080:localhost:80') when IPv6 is not required
Example fix
# before ssh -L '[8080:localhost:80' user@host # after ssh -L '[::1]:8080:localhost:80' user@host
Defensive patterns
Strategy: validation
Validate before calling
fn port_forward_spec_balanced(spec: &str) -> bool {
let mut open = 0usize;
for ch in spec.chars() {
match ch {
'[' => open += 1,
']' => open = open.saturating_sub(1),
_ => {}
}
}
open == 0
} Try / catch
match SshConnectionOptions::parse_command_line(input) {
Err(e) if e.to_string().contains("Unmatched '['") => {
// reject the input early and show the offending spec to the user
Err(e)
}
other => other,
} Prevention
- Validate bracket balance before parsing -L/-R specs
- Quote the whole spec when passing through shells to keep brackets intact
- Bracket only the IPv6 literal, never the whole spec
When it happens
Trigger: parse_port_forward_spec routes a spec containing '[' into split_port_forward_tokens, whose inner loop hits None before finding ']' — e.g. '[::1:8080:localhost:80' or any truncated/misquoted IPv6 bind address.
Common situations: Hand-writing port forward options and dropping the closing bracket around an IPv6 literal; shell quoting that strips ']' when passing the argument; copy-pasting from docs or chat that mangled bracket characters.
Related errors
- build ids may only contain lowercase letters, numbers, '.',
- registry dataset requires a name
- cannot open repository on disconnected remote machine
- user is empty in wsl argument
- OAuth endpoint must not point to private/reserved IP: ::ffff
AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20).
Data as JSON: /api/errors/5e571de9ffdf03a1.
Report an issue: GitHub.