{"record":{"id":"981ed94b3047ea6e","repo":"v2rayA/v2rayA","slug":"v","errorCode":null,"errorMessage":"%v","messagePattern":"%v","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/kernel/v2ray/process.go","lineNumber":77,"sourceCode":"\t// v2rayA 仅负责生成配置和在透明代理时应用防火墙规则。\n\tif tmpl.Setting != nil && tmpl.DnsModuleConfig != nil {\n\t\tlog.Info(\"DNS module config written to v2raya-core config\")\n\t}\n\tif tmpl.MultiObservatory != nil {\n\t\t// NOTICE: tag2WhichIndex is reliable because once connected servers are changed when v2ray is running,\n\t\t// the func UpdateV2RayConfig should be invoked and tag2WhichIndex will be regenerated.\n\t\ttag2WhichIndex := make(map[string]int)\n\t\tfor i, tag := range tmpl.OutboundTags {\n\t\t\ttag2WhichIndex[tag] = i\n\t\t}\n\t\tprocess.tag2WhichIndex = tag2WhichIndex\n\t}\n\terr = WriteV2rayConfig(tmpl.ToConfigBytes())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err = tmpl.CheckInboundPortsOccupied(); err != nil {\n\t\treturn nil, fmt.Errorf(\"%v\", err)\n\t}\n\tpCtx, cancel := context.WithCancel(context.Background())\n\tdefer func() {\n\t\tif err != nil {\n\t\t\tcancel()\n\t\t}\n\t}()\n\tdefer func() {\n\t\tif err != nil {\n\t\t\t_ = tmpl.Close()\n\t\t}\n\t}()\n\tif tmpl.API == nil {\n\t\tlog.Fatal(\"unexpected tmpl.API == nil\")\n\t}\n\tprocess.procCancel = cancel\n\tif err = prestart(); err != nil {\n\t\treturn nil, err","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/v2rayA/v2rayA/blob/71e5442fc548c05680ee55eae943e6c0afe9ac51/service/kernel/v2ray/process.go#L59-L95","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Find the holder with 'sudo ss -tlnp' or 'lsof -i :<port>' and kill the stale process (often an orphaned v2ray/xray).","Change the conflicting inbound port in v2rayA settings (port range preferences).","Restart v2rayA so its ProcessManager cleans up previous core instances before starting a new one.","Check for duplicate inbound port configuration if you customized inbounds."],"exampleFix":"// before\n$ ss -tlnp | grep 20170\nusers:((\"xray\",pid=999,...))\n\n// after\n$ sudo kill 999   # stale core instance","handlingStrategy":"validation","validationCode":"// probe inbound ports before start\nif tmpl != nil {\n    if err := tmpl.CheckInboundPortsOccupied(); err != nil {\n        // free or remap ports before calling Start\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := tmpl.CheckInboundPortsOccupied(); err != nil {\n    return fmt.Errorf(\"inbound port conflict, adjust ports: %w\", err)\n}","preventionTips":["Kill stale v2ray/xray processes before starting a new core","Choose non-default inbound ports if other proxies run on the host","Avoid duplicate inbound ports in customized settings","Check 'ss -tlnp' for the configured ports after any crash"],"tags":["v2ray","port-conflict","process-start"],"backgroundTag":"port-already-in-use","analyzedSha":"71e5442fc548c05680ee55eae943e6c0afe9ac51","analyzedAt":"2026-09-05T20:04:37.459Z","contentChangedAt":"2026-09-05T20:04:37.459Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}