XTLS/Xray-core · warning

failed to create mux client worker

Error message

failed to create mux client worker

What it means

Portal-side failure to create the mux client that carries all tunneled connections over the single portal connection: mux.NewClientWorker(*link, mux.ClientStrategy{}) returned an error. Marked AtWarning because the tunnel setup failed but the instance keeps running. NewClientWorker can fail when the supplied link is already closed/broken or mux worker internals (pipe/queue init) fail.

Source

Thrown at app/reverse/portal.go:77

		tag:    p.tag,
	})
}

func (p *Portal) Close() error {
	return p.ohm.RemoveHandler(context.Background(), p.tag)
}

func (p *Portal) HandleConnection(ctx context.Context, link *transport.Link) error {
	outbounds := session.OutboundsFromContext(ctx)
	ob := outbounds[len(outbounds)-1]
	if ob == nil {
		return errors.New("outbound metadata not found").AtError()
	}

	if isDomain(ob.Target, p.domain) {
		muxClient, err := mux.NewClientWorker(*link, mux.ClientStrategy{})
		if err != nil {
			return errors.New("failed to create mux client worker").Base(err).AtWarning()
		}

		worker, err := NewPortalWorker(muxClient)
		if err != nil {
			return errors.New("failed to create portal worker").Base(err)
		}

		p.picker.AddWorker(worker)

		if _, ok := link.Reader.(*pipe.Reader); !ok {
			select {
			case <-ctx.Done():
			case <-muxClient.WaitClosed():
			}
		}
		return nil
	}

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Check bridge-to-portal connectivity and stability (the underlying carrier connection must be healthy when the portal accepts it).
  2. Upgrade xray-core; mux client worker initialization has had fixes across releases.
  3. If embedding, verify the link passed to HandleConnection is freshly created and open, not shared or pre-closed.
Defensive patterns

Strategy: retry

Validate before calling

// Ensure the link is open before tunnel setup
if link.Reader == nil || link.Writer == nil { return errors.New("invalid link for portal tunnel") }
// optionally probe: write a zero-length keepalive to detect dead links

Try / catch

if err := portal.HandleConnection(ctx, link); err != nil {
    if strings.Contains(err.Error(), "failed to create mux client worker") {
        closeLink(link) // session is unusable; let the bridge reconnect fresh
        return nil     // transient: next bridge connection retries
    }
    return err
}

Prevention

When it happens

Trigger: A connection dispatched to the portal whose target domain matches p.domain, but whose transport.Link reader/writer is unusable — e.g. the inbound connection died between accept and portal dispatch, or a custom caller passed an already-closed pipe pair to HandleConnection.

Common situations: Flaky upstream connections between bridge and portal dropping right at tunnel establishment; memory pressure or bugs in older core versions where client worker init fails; custom integrations reusing link objects. Rare in stock deployments.

Related errors


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