XTLS/Xray-core · info

failed to fallback request payload

Error message

failed to fallback request payload

What it means

Uplink copy from the trojan client to the fallback backend failed (buf.Copy reader→serverWriter) during fallback relaying. AtInfo severity: fallback traffic is best-effort camouflage of already-rejected trojan traffic, so failures are informational.

Source

Thrown at proxy/trojan/server.go:527

				if ipType == 4 {
					common.Must2(pro.Write([]byte("\x21\x11\x00\x0C"))) // v2 + PROXY + AF_INET + STREAM + 12 bytes
					common.Must2(pro.Write(net.ParseIP(remoteAddr).To4()))
					common.Must2(pro.Write(net.ParseIP(localAddr).To4()))
				} else {
					common.Must2(pro.Write([]byte("\x21\x21\x00\x24"))) // v2 + PROXY + AF_INET6 + STREAM + 36 bytes
					common.Must2(pro.Write(net.ParseIP(remoteAddr).To16()))
					common.Must2(pro.Write(net.ParseIP(localAddr).To16()))
				}
				p1, _ := strconv.ParseUint(remotePort, 10, 16)
				p2, _ := strconv.ParseUint(localPort, 10, 16)
				common.Must2(pro.Write([]byte{byte(p1 >> 8), byte(p1), byte(p2 >> 8), byte(p2)}))
			}
			if err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pro}); err != nil {
				return errors.New("failed to set PROXY protocol v", fb.Xver).Base(err).AtWarning()
			}
		}
		if err := buf.Copy(reader, serverWriter, buf.UpdateActivity(timer)); err != nil {
			return errors.New("failed to fallback request payload").Base(err).AtInfo()
		}
		return nil
	}

	writer := buf.NewWriter(connection)

	getResponse := func() error {
		defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
		if err := buf.Copy(serverReader, writer, buf.UpdateActivity(timer)); err != nil {
			return errors.New("failed to deliver response payload").Base(err).AtInfo()
		}
		return nil
	}

	if err := task.Run(ctx, task.OnSuccess(postRequest, task.Close(serverWriter)), task.OnSuccess(getResponse, task.Close(writer))); err != nil {
		common.Must(common.Interrupt(serverReader))
		common.Must(common.Interrupt(serverWriter))
		return errors.New("fallback ends").Base(err).AtInfo()

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Usually no action: verify the backend responded as intended
  2. If backends close immediately, review whether they expect PROXY protocol (see [731])
  3. Ignore unless fallback traffic genuinely needs relay fidelity
Defensive patterns

Strategy: try-catch

Try / catch

if err := buf.Copy(reader, serverWriter, buf.UpdateActivity(timer)); err != nil {
    // best-effort fallback uplink; failure just ends the fallback relay
    return errors.New("failed to fallback request payload").Base(err).AtInfo()
}

Prevention

When it happens

Trigger: Client disconnects mid-fallback, backend closes early (it already got enough bytes to respond, e.g. a 400), or the idle timer cancels the context.

Common situations: Scanners/probers that half-close after sending a request; backend rejecting garbage with an immediate close.

Related errors


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