{"record":{"id":"1c13ff1095896ce7","repo":"XTLS/Xray-core","slug":"conflict","errorCode":null,"errorMessage":"conflict","messagePattern":"conflict","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"common/mux/server.go","lineNumber":209,"sourceCode":"\t\t\treturn errors.New(\"unexpected network \", meta.Target.Network) // it will break the whole Mux connection\n\t\t}\n\t}\n\n\tif meta.GlobalID != [8]byte{} { // MUST ignore empty Global ID\n\t\tmb, err := NewPacketReader(reader, &meta.Target).ReadMultiBuffer()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tXUDPManager.Lock()\n\t\tx := XUDPManager.Map[meta.GlobalID]\n\t\tif x == nil {\n\t\t\tx = &XUDP{GlobalID: meta.GlobalID}\n\t\t\tXUDPManager.Map[meta.GlobalID] = x\n\t\t\tXUDPManager.Unlock()\n\t\t} else {\n\t\t\tif x.Status == Initializing { // nearly impossible\n\t\t\t\tXUDPManager.Unlock()\n\t\t\t\terrors.LogWarningInner(ctx, errors.New(\"conflict\"), \"XUDP hit \", meta.GlobalID)\n\t\t\t\t// It's not a good idea to return an err here, so just let client wait.\n\t\t\t\t// Client will receive an End frame after sending a Keep frame.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tx.Status = Initializing\n\t\t\tXUDPManager.Unlock()\n\t\t\tx.Mux.Close(false) // detach from previous Mux\n\t\t\tb := buf.New()\n\t\t\tb.Write(mb[0].Bytes())\n\t\t\tb.UDP = mb[0].UDP\n\t\t\tif err = x.Mux.output.WriteMultiBuffer(mb); err != nil {\n\t\t\t\tx.Interrupt()\n\t\t\t\tmb = buf.MultiBuffer{b}\n\t\t\t} else {\n\t\t\t\tb.Release()\n\t\t\t\tmb = nil\n\t\t\t}\n\t\t\terrors.LogInfoInner(ctx, err, \"XUDP hit \", meta.GlobalID)","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/common/mux/server.go#L191-L227","documentation":"Two XUDP sessions with the same GlobalID arrived while the first was still Initializing (before its dispatch completed). The server logs this as a warning and deliberately returns nil (no error), letting the second client wait; the first client will get an End frame after sending a Keep frame. The 'conflict' error object exists only for logging and is never propagated.","triggerScenarios":"Concurrent XUDP session establishment where a second frame with an identical 8-byte GlobalID races the first before its status flips from Initializing to Active.","commonSituations":"Client retry storms, duplicated frames by the transport, or two processes reusing the same GlobalID. Developers grep logs, see 'conflict', and assume a failure; it is informational.","solutions":["Treat the log line as benign unless XUDP sessions actually hang; no server-side fix is required.","On the client, avoid reusing GlobalIDs across concurrent connection attempts (generate a fresh ID per session).","If it floods the logs, upgrade Xray-core (handling of the race has been refined over versions).","Confirm the waiting client eventually resumes; if it never does, capture the frame sequence for a bug report."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"// No catch needed: the server already swallows this path and returns nil.\n// Client side, handle the subsequent End frame after Keep:\nif status == SessionStatusEnd && isXUDP {\n    reinitializeXudpSession(newGlobalID) // server asked us to restart\n}","preventionTips":["Generate a fresh GlobalID per XUDP session to avoid colliding with Initializing entries.","Do not spam duplicate New frames with the same GlobalID during retries.","Treat the 'conflict' warning line as informational, not a failure."],"tags":["mux","xudp","concurrency","logging","xray"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}