shadow1ng/fscan · error

%s: %w [listen_port_failed]

Error message

%s: %w [listen_port_failed]

What it means

Wrap of a net.Listen failure in startSocks5Server: the SOCKS5 proxy server could not bind/listen on 0.0.0.0:<port> (most commonly the port is already in use or privileges are insufficient). The i18n listen_port_failed prefix plus %w preserve the underlying network error; the deferred listener cleanup never runs because the listener was never created.

Source

Thrown at plugins/local/socks5proxy.go:83

	}

	output.WriteString(i18n.GetText("socks5_done") + "\n")
	session.LogSuccess(i18n.Tr("socks5_complete", port))

	return &plugins.Result{
		Success: true,
		Type:    plugins.ResultTypeService,
		Output:  output.String(),
		Error:   nil,
	}
}

// startSocks5Server 启动SOCKS5代理服务器 - 核心实现
func (p *Socks5ProxyPlugin) startSocks5Server(ctx context.Context, port int, state *common.State, session *common.ScanSession) error {
	// 监听指定端口
	listener, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", port))
	if err != nil {
		return fmt.Errorf("%s: %w", i18n.GetText("listen_port_failed"), err)
	}
	defer func() { _ = listener.Close() }()

	p.listener = listener
	session.LogSuccess(i18n.Tr("socks5_started", port))

	// 设置SOCKS5代理为活跃状态,告诉主程序保持运行
	state.SetSocks5ProxyActive(true)
	defer func() {
		// 确保退出时清除活跃状态
		state.SetSocks5ProxyActive(false)
	}()

	// 主循环处理连接
	for {
		select {
		case <-ctx.Done():
			session.LogInfo(i18n.GetText("socks5_cancelled"))

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Check what holds the port (netstat -ano | findstr <port> / ss -ltnp) and stop it or choose a different port.
  2. Configure the plugin with a high, unprivileged port (e.g. 1080, 18080).
  3. On Linux, grant CAP_NET_BIND_SERVICE or use sysctl net.ipv4.ip_unprivileged_port_start if a low port is required.
  4. Retry with port 0 to auto-assign a free ephemeral port if the port is not fixed by the tooling.

Example fix

// before
listener, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", port))
// after — fail fast with a clear EADDRINUSE message
listener, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", port))
if err != nil {
	var opErr *net.OpError
	if errors.As(err, &opErr) && errors.Is(opErr.Err, syscall.EADDRINUSE) {
		return fmt.Errorf("port %d in use, pick another: %w", port, err)
	}
	return fmt.Errorf("%s: %w", i18n.GetText("listen_port_failed"), err)
}
Defensive patterns

Strategy: retry

Validate before calling

func portFree(port int) bool {
	l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port))
	if err != nil {
		return false
	}
	_ = l.Close()
	return true
}

Type guard

func isAddrInUse(err error) bool {
	var opErr *net.OpError
	return errors.As(err, &opErr) && errors.Is(opErr.Err, syscall.EADDRINUSE)
}

Try / catch

listener, err := net.Listen("tcp", addr)
if err != nil {
	if isAddrInUse(err) {
		// pick another port or notify user
	}
	return fmt.Errorf("%s: %w", i18n.GetText("listen_port_failed"), err)
}

Prevention

When it happens

Trigger: net.Listen("tcp", "0.0.0.0:port") returns err inside startSocks5Server — port already bound by another process, port is privileged (<1024) without rights, or binding to 0.0.0.0 is blocked.

Common situations: Another instance of the plugin/proxy still running on the same port; configured port collides with a local service; running in a container/sandbox without the port mapped or permitted.

Related errors


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/5231cf3a8eeef8bf. Report an issue: GitHub.