juicedata/juicefs · warning
failed to parse listen port: %v
Error message
failed to parse listen port: %v
What it means
During `juicefs debug` pprof-port discovery, getPprofPort parses each `lsof -i -nP` LISTEN line for the target PID and extracts the port by splitting the second-to-last field on ':' and taking index 1. The parse runs inside an anonymous func with a deferred recover, so any panic (notably an index-out-of-range from splitting an address that contains no ':') is converted into this wrapped error. The wrapping exists precisely so one malformed lsof line cannot crash the whole debug command.
Source
Thrown at cmd/debug.go:195
ret, err := exec.Command(lsofArgs[0], lsofArgs[1:]...).CombinedOutput()
if err != nil {
return 0, fmt.Errorf("failed to execute command `%s`: %v", strings.Join(lsofArgs, " "), err)
}
logger.Debugf("lsof output: \n%s", string(ret))
lines := strings.Split(string(ret), "\n")
if len(lines) == 0 {
return 0, fmt.Errorf("pprof will be collected, but no listen port")
}
var listenPort = -1
for _, line := range lines {
fields := strings.Fields(line)
if len(fields) != 0 {
port, err := func() (port int, err error) {
defer func() {
e := recover()
if e != nil {
err = fmt.Errorf("failed to parse listen port: %v", e)
}
}()
port, err = strconv.Atoi(strings.Split(fields[len(fields)-2], ":")[1])
if err != nil {
logger.Errorf("failed to parse port %v: %v", port, err)
}
return
}()
if err != nil {
continue
}
if port >= 6060 && port <= 6099 && port > listenPort {
if err := checkPort(port, amp); err == nil {
listenPort = port
}
continue
}
}View on GitHub (pinned to c9a67b23e8)
Solutions
- Ignore safely: getPprofPort already `continue`s past lines that produce this error; verify other candidate ports in the 6060-6099 range are being tried.
- Run `/bin/sh -c "lsof -i -nP | grep LISTEN | grep <pid>"` manually and inspect lines whose second-to-last field lacks a ':'; those are the offenders.
- Ensure the JuiceFS mount exposes pprof (default net/http/pprof on 6060+) so a valid TCP line exists among lsof output.
- Check lsof version/platform differences; prefer parsing the `*:PORT` / `127.0.0.1:PORT` address column explicitly rather than the second-to-last field.
Example fix
// before
port, err = strconv.Atoi(strings.Split(fields[len(fields)-2], ":")[1])
// after
addr := fields[len(fields)-2]
if i := strings.LastIndex(addr, ":"); i >= 0 {
port, err = strconv.Atoi(addr[i+1:])
} else {
err = fmt.Errorf("no port in address %q", addr)
} Defensive patterns
Strategy: validation
Validate before calling
addr := fields[len(fields)-2]
if i := strings.LastIndex(addr, ":"); i < 0 || i == len(addr)-1 {
return fmt.Errorf("skipping line: no parsable port in address %q", addr)
}
port, err := strconv.Atoi(addr[i+1:]) Type guard
func hasPort(addr string) bool {
i := strings.LastIndex(addr, ":")
return i >= 0 && i < len(addr)-1
} Try / catch
// Go: recover converted to error (already used in getPprofPort)
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("failed to parse listen port: %v", e)
}
}() Prevention
- Never index strings.Split results without checking lengths; use strings.LastIndex on the address instead.
- Test the lsof-parsing code against IPv6 and Unix-socket LISTEN lines.
- Treat each unparsable lsof line as skip-and-continue, not fatal.
When it happens
Trigger: `juicefs debug <mountpoint>` runs lsof and a LISTEN line has fewer than 2 whitespace fields, or its second-to-last field is an address without ':' (e.g. a Unix socket line, an IPv6/pcrec-format line, or `fields[len(fields)-2]` being the PID itself), causing strings.Split(..., ":")[1] to panic. The recover converts the panic into 'failed to parse listen port: %v'.
Common situations: Environments whose lsof emits non-standard LISTEN lines (busybox lsof, unusual locales, IPv6 addresses, extra columns); the mount was started with a Unix-domain socket instead of a TCP listener; PID reuse picks up unrelated processes with non-TCP listening sockets.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to execute command `%s`: %v
- error creating GET request: %v
- error GET request: %v
- error GET request, status code %d
- recovered from %s
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/8b7cfec3e9bf4694.
Report an issue: GitHub.