XTLS/Xray-core · error · errors.Error
unable to get destination
Error message
unable to get destination
What it means
The dokodemo-door process callback derives the real destination either from config (address), from UDP session targets, or from the original-destination info on the connection (SO_ORIGINAL_DST / recvfrom). If none yields a valid destination (dest invalid or nil address), processing aborts with this error. This is the classic transparent-proxy failure: the inbound cannot discover where the intercepted connection originally headed.
Source
Thrown at proxy/dokodemo/dokodemo.go:135
if ob.Target.IsValid() {
dest = ob.Target
destinationOverridden = true
}
}
iConn := stat.TryUnwrapStatsConn(conn)
if tlsConn, ok := iConn.(tls.Interface); ok && !destinationOverridden {
if serverName := tlsConn.HandshakeContextServerName(ctx); serverName != "" {
dest.Address = net.DomainAddress(serverName)
destinationOverridden = true
ctx = session.ContextWithMitmServerName(ctx, serverName)
}
if tlsConn.NegotiatedProtocol() != "h2" {
ctx = session.ContextWithMitmAlpn11(ctx, true)
}
}
}
if !dest.IsValid() || dest.Address == nil {
return errors.New("unable to get destination")
}
inbound := session.InboundFromContext(ctx)
inbound.Name = "dokodemo-door"
inbound.CanSpliceCopy = 1
inbound.User = &protocol.MemoryUser{
Level: d.config.UserLevel,
}
ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
From: conn.RemoteAddr(),
To: dest,
Status: log.AccessAccepted,
Reason: "",
})
errors.LogInfo(ctx, "received request for ", conn.RemoteAddr())
var reader buf.ReaderView on GitHub (pinned to 7d214f8b09)
Solutions
- Verify redirect rules exist and match the traffic: iptables -t nat -L -n / nft list ruleset; REDIRECT for nat path, TPROXY with mangle for tproxy path
- Ensure the dokodemo inbound option matches the redirection method (followRedirect vs tproxy setting)
- If you do not need original-destination, set an explicit "address" (and "port") in inbound settings so dest is always known
- Cover IPv6 (ip6tables/nft inet family) if clients connect over v6
Example fix
# before: plain DNAT loses original destination iptables -t nat -A PREROUTING -p tcp -d $EXT_IP --dport 80 -j DNAT --to-destination 127.0.0.1:1080 # after: REDIRECT preserves it for followRedirect iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 80 -j REDIRECT --to-ports 1080
Defensive patterns
Strategy: validation
Validate before calling
// pre-flight: ensure original-destination retrieval works for this traffic
if followRedirect {
if !redirectRulesExist("nat") { fatal("missing iptables REDIRECT rules") }
} else if settings.Address == nil {
fatal("dokodemo needs address or original-destination mode")
} Try / catch
if err := d.process(ctx, link, dialer); err != nil {
if err.Error() == "unable to get destination" { logCaptureHintAndDrop(ctx); return nil }
return err
} Prevention
- Keep iptables/nftables redirect rules in a managed, idempotent script applied before Xray starts
- Cover both IPv4 and IPv6 with matching rules
- When original-destination is unreliable (containers/NAT), set explicit address/port in dokodemo settings
- Re-apply firewall rules after any firewall refresh before blaming Xray
When it happens
Trigger: Using dokodemo with followRedirect/followOriginalDestination but traffic reaches it via plain DNAT/REDIRECT without proper iptables/nftables REDIRECT target, no TPROXY mark, or a protocol (e.g. ICMP) exposing no original destination; also "address" left empty when not following destination.
Common situations: Missing or wrong iptables rules (NAT table REDIRECT vs mangle TPROXY), Docker NAT'd traffic losing original dst, IPv6 traffic not covered by the rules, or misordered rules after firewall refresh; TLS serverName extraction path (seen in source) only applies when MITM is active.
Related errors
- outbound failed to relay connection
- invalid portMap: {}
- failed to dial to
- no network specified
- failed to dispatch request
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/c16e6776aa323b93.
Report an issue: GitHub.