XTLS/Xray-core · error

failed to create request from: ${remoteAddr}

Error message

failed to create request from: ${remoteAddr}

What it means

Returned by the trojan inbound server when ConnReader.ParseHeader() fails while parsing the first bytes of a decrypted TLS payload. ParseHeader expects the fixed trojan layout: 56-byte hex user hash, CRLF, 1-byte command (TCP/UDP), SOCKS-style address+port, CRLF. Any short read, bad address, or non-trojan byte stream produces this error, which also records an AccessRejected log entry before returning.

Source

Thrown at proxy/trojan/server.go:217

			shouldFallback = true
		}
	}

	if isfb && shouldFallback {
		return s.fallback(ctx, err, sessionPolicy, conn, iConn, napfb, first, firstLen, bufferedReader)
	} else if shouldFallback {
		return errors.New("invalid protocol or invalid user")
	}

	clientReader := &ConnReader{Reader: bufferedReader}
	if err := clientReader.ParseHeader(); err != nil {
		log.Record(&log.AccessMessage{
			From:   conn.RemoteAddr(),
			To:     "",
			Status: log.AccessRejected,
			Reason: err,
		})
		return errors.New("failed to create request from: ", conn.RemoteAddr()).Base(err)
	}

	destination := clientReader.Target
	if err := conn.SetReadDeadline(time.Time{}); err != nil {
		return errors.New("unable to set read deadline").Base(err).AtWarning()
	}

	inbound := session.InboundFromContext(ctx)
	inbound.Name = "trojan"
	inbound.CanSpliceCopy = 3
	inbound.User = user
	sessionPolicy = s.policyManager.ForLevel(user.Level)

	if destination.Network == net.Network_UDP { // handle udp request
		return s.handleUDPPayload(ctx, sessionPolicy, &PacketReader{Reader: clientReader}, &PacketWriter{Writer: conn}, dispatcher)
	}

	ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Verify the client is a real trojan client and its password matches a configured user (the 56-byte hex SHA-224 of the password must equal a stored key)
  2. If you must share the port with other protocols, configure fallbacks in the trojan inbound so non-trojan traffic is relayed instead of rejected
  3. Check the access log entry (AccessRejected with the Base cause: 'failed to read user hash' vs 'failed to read address and port') to see which header stage failed
  4. Capture the client hello with tcpdump/tls debugging to confirm what bytes actually arrive after TLS termination

Example fix

// json config: give non-trojan TLS traffic a fallback
"inbounds": [{
  "protocol": "trojan",
  "port": 443,
  "settings": {
    "clients": [{"password": "pw", "email": "a@b.c"}],
    "fallbacks": [{"dest": 8080}]
  }
}]
Defensive patterns

Strategy: validation

Validate before calling

// Pre-accept check: only route real trojan traffic to this inbound; give
// everything else a fallback. Config-level prevention:
//   "fallbacks": [{"dest": 80}]
// ensures ParseHeader failures fall back instead of surfacing this error.

Try / catch

if err := s.processConnection(ctx, conn, dispatcher); err != nil {
    if strings.Contains(err.Error(), "failed to create request from") {
        // non-trojan or garbage TLS payload: log at debug and close
        errors.LogDebug(ctx, "non-trojan client: ", err)
        return
    }
    return err
}

Prevention

When it happens

Trigger: A TLS client connects to the trojan port but speaks a different protocol (plain HTTP, another proxy protocol), the client sends fewer than 56 bytes and disconnects, the address parser hits a malformed SOCKS address type, or the client trojan implementation writes an invalid header. Raised in Server.handleConnection after the fallback check decided not to fall back.

Common situations: Health probes or scanners hitting the trojan port, a client with a password-hash length mismatch, sharing the port with non-trojan clients without configuring fallbacks, or version drift where the client uses a different trojan header variant.

Related errors


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