XTLS/Xray-core · info
conflict
Error message
conflict
What it means
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.
Source
Thrown at common/mux/server.go:209
return errors.New("unexpected network ", meta.Target.Network) // it will break the whole Mux connection
}
}
if meta.GlobalID != [8]byte{} { // MUST ignore empty Global ID
mb, err := NewPacketReader(reader, &meta.Target).ReadMultiBuffer()
if err != nil {
return err
}
XUDPManager.Lock()
x := XUDPManager.Map[meta.GlobalID]
if x == nil {
x = &XUDP{GlobalID: meta.GlobalID}
XUDPManager.Map[meta.GlobalID] = x
XUDPManager.Unlock()
} else {
if x.Status == Initializing { // nearly impossible
XUDPManager.Unlock()
errors.LogWarningInner(ctx, errors.New("conflict"), "XUDP hit ", meta.GlobalID)
// It's not a good idea to return an err here, so just let client wait.
// Client will receive an End frame after sending a Keep frame.
return nil
}
x.Status = Initializing
XUDPManager.Unlock()
x.Mux.Close(false) // detach from previous Mux
b := buf.New()
b.Write(mb[0].Bytes())
b.UDP = mb[0].UDP
if err = x.Mux.output.WriteMultiBuffer(mb); err != nil {
x.Interrupt()
mb = buf.MultiBuffer{b}
} else {
b.Release()
mb = nil
}
errors.LogInfoInner(ctx, err, "XUDP hit ", meta.GlobalID)View on GitHub (pinned to 7d214f8b09)
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.
Defensive patterns
Strategy: fallback
Try / catch
// No catch needed: the server already swallows this path and returns nil.
// Client side, handle the subsequent End frame after Keep:
if status == SessionStatusEnd && isXUDP {
reinitializeXudpSession(newGlobalID) // server asked us to restart
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- failed to process mux outbound traffic
- unable to find an available mux client
- packet size too large:
- XUDP new
- failed to add new session
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/1c13ff1095896ce7.
Report an issue: GitHub.