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

  1. Treat the log line as benign unless XUDP sessions actually hang; no server-side fix is required.
  2. On the client, avoid reusing GlobalIDs across concurrent connection attempts (generate a fresh ID per session).
  3. If it floods the logs, upgrade Xray-core (handling of the race has been refined over versions).
  4. 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

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


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/1c13ff1095896ce7. Report an issue: GitHub.