v2rayA/v2rayA · error

%v

Error message

%v

What it means

In NewProcess, after writing the generated v2ray config to disk, the template's inbound ports are checked and CheckInboundPortsOccupied's error is re-wrapped verbatim with fmt.Errorf("%v", err). It means one of the inbound ports the new v2ray template wants to bind (socks/http/transparent inbounds) is already taken, so the core cannot be started with this configuration.

Source

Thrown at service/kernel/v2ray/process.go:77

	// v2rayA 仅负责生成配置和在透明代理时应用防火墙规则。
	if tmpl.Setting != nil && tmpl.DnsModuleConfig != nil {
		log.Info("DNS module config written to v2raya-core config")
	}
	if tmpl.MultiObservatory != nil {
		// NOTICE: tag2WhichIndex is reliable because once connected servers are changed when v2ray is running,
		// the func UpdateV2RayConfig should be invoked and tag2WhichIndex will be regenerated.
		tag2WhichIndex := make(map[string]int)
		for i, tag := range tmpl.OutboundTags {
			tag2WhichIndex[tag] = i
		}
		process.tag2WhichIndex = tag2WhichIndex
	}
	err = WriteV2rayConfig(tmpl.ToConfigBytes())
	if err != nil {
		return nil, err
	}
	if err = tmpl.CheckInboundPortsOccupied(); err != nil {
		return nil, fmt.Errorf("%v", err)
	}
	pCtx, cancel := context.WithCancel(context.Background())
	defer func() {
		if err != nil {
			cancel()
		}
	}()
	defer func() {
		if err != nil {
			_ = tmpl.Close()
		}
	}()
	if tmpl.API == nil {
		log.Fatal("unexpected tmpl.API == nil")
	}
	process.procCancel = cancel
	if err = prestart(); err != nil {
		return nil, err

View on GitHub (pinned to 71e5442fc5)

Solutions

  1. Find the holder with 'sudo ss -tlnp' or 'lsof -i :<port>' and kill the stale process (often an orphaned v2ray/xray).
  2. Change the conflicting inbound port in v2rayA settings (port range preferences).
  3. Restart v2rayA so its ProcessManager cleans up previous core instances before starting a new one.
  4. Check for duplicate inbound port configuration if you customized inbounds.

Example fix

// before
$ ss -tlnp | grep 20170
users:(("xray",pid=999,...))

// after
$ sudo kill 999   # stale core instance
Defensive patterns

Strategy: validation

Validate before calling

// probe inbound ports before start
if tmpl != nil {
    if err := tmpl.CheckInboundPortsOccupied(); err != nil {
        // free or remap ports before calling Start
    }
}

Try / catch

if err := tmpl.CheckInboundPortsOccupied(); err != nil {
    return fmt.Errorf("inbound port conflict, adjust ports: %w", err)
}

Prevention

When it happens

Trigger: Calling NewProcess (via Start) when an inbound port in tmpl conflicts with an already-listening socket — typically a previous v2ray/xray instance that did not shut down, or another local proxy using the same socks/http port.

Common situations: Zombie v2ray-core processes from an earlier crashed session still holding 20170/20171/etc.; running another proxy client (clash, shadowsocks) on the same inbound port; duplicated inbound port values in user-defined inbound settings.

Related errors


AI-assisted analysis of v2rayA/v2rayA@71e5442fc5 (2026-09-05). Data as JSON: /api/errors/981ed94b3047ea6e. Report an issue: GitHub.