XTLS/Xray-core · error · errors.Error

failed to process response

Error message

failed to process response

What it means

The downlink copy (remote → client) failed during buf.Copy(reader, output). The reader is a stream reader for TCP or NewPacketReader for UDP; any read error from the remote conn, write error to the inbound writer, or activity-timer expiry surfaces here, wrapped as "failed to process response".

Source

Thrown at proxy/freedom/freedom.go:449

	responseDone := func() error {
		defer timer.SetTimeout(plcy.Timeouts.UplinkOnly)
		if destination.Network == net.Network_TCP && useSplice.Load() && proxy.IsRAWTransportWithoutSecurity(conn) { // it would be tls conn in special use case of MITM, we need to let link handle traffic
			var writeConn net.Conn
			var inTimer *signal.ActivityTimer
			if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Conn != nil {
				writeConn = inbound.Conn
				inTimer = inbound.Timer
			}
			return proxy.CopyRawConnIfExist(ctx, conn, writeConn, link.Writer, timer, inTimer)
		}
		var reader buf.Reader
		if destination.Network == net.Network_TCP {
			reader = buf.NewReader(conn)
		} else {
			reader = NewPacketReader(conn, h, defaultRule, UDPOverride, destination)
		}
		if err := buf.Copy(reader, output, buf.UpdateActivity(timer)); err != nil {
			return errors.New("failed to process response").Base(err)
		}
		return nil
	}

	if newCtx != nil {
		ctx = newCtx
	}

	if err := task.Run(ctx, requestDone, task.OnSuccess(responseDone, task.Close(output))); err != nil {
		return errors.New("connection ends").Base(err)
	}

	return nil
}

func NewPacketReader(conn net.Conn, h *Handler, defaultRule *FinalRule, UDPOverride net.Destination, DialDest net.Destination) buf.Reader {
	iConn := conn
	statConn, ok := iConn.(*stat.CounterConnection)

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Inspect the Base error for io.EOF/ErrTimeout/reset signatures
  2. Raise policy.Timeouts.downlinkOnly if servers legitimately pause between responses
  3. For UDP, ensure session limits (policy.levels handshake/connIdle) fit the application's inter-packet gaps
  4. Check for path MTU issues if transfers stall deterministically at the same size
Defensive patterns

Strategy: try-catch

Try / catch

```go
if err := h.Process(ctx, link, dialer); err != nil {
    if errors.Is(err, io.EOF) { return }
    if errors.Is(err, os.ErrDeadlineExceeded) { /* raise downlinkOnly */ }
}
```

Prevention

When it happens

Trigger: Remote server closes or RESETs mid-response, write to the client link fails (client went away), UDP session timeout in NewPacketReader, or downlinkOnly policy timeout firing while waiting for server data.

Common situations: Server-side idle timeouts (e.g. nginx keepalive) closing the flow, mobile clients backgrounding the app and dropping the socket, small downlinkOnly timeout on slow APIs, UDP NAT expiry mid-session.

Related errors


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