XTLS/Xray-core · error · errors.Error

target not specified.

Error message

target not specified.

What it means

The freedom outbound's Process found the last outbound object in the session context has an invalid Target (no address, no port, or zero network). Freedom is a direct-dial outbound: it must know exactly where to connect, so it refuses to proceed without a valid destination.

Source

Thrown at proxy/freedom/freedom.go:254

	}
	return time.Duration(min+uint64(dice.Roll(int(span+1)))) * time.Second
}

func isValidAddress(addr *net.IPOrDomain) bool {
	if addr == nil {
		return false
	}

	a := addr.AsAddress()
	return a != net.AnyIP && a != net.AnyIPv6
}

// Process implements proxy.Outbound.
func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {
	outbounds := session.OutboundsFromContext(ctx)
	ob := outbounds[len(outbounds)-1]
	if !ob.Target.IsValid() {
		return errors.New("target not specified.")
	}
	ob.Name = "freedom"
	ob.CanSpliceCopy = 1
	inbound := session.InboundFromContext(ctx)
	defaultRule := getDefaultFinalRule(inbound)

	destination := ob.Target
	origTargetAddr := ob.OriginalTarget.Address
	if origTargetAddr == nil {
		origTargetAddr = ob.Target.Address
	}
	dialer.SetOutboundGateway(ctx, ob)
	outGateway := ob.Gateway
	UDPOverride := net.UDPDestination(nil, 0)
	if h.config.DestinationOverride != nil {
		server := h.config.DestinationOverride.Server
		if isValidAddress(server.Address) {
			destination.Address = server.Address.AsAddress()

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Verify the inbound actually resolves the destination (e.g. transparent proxy iptables/nftables rules are correct so original dst is available)
  2. Check routing rules: do not route traffic without a valid target (e.g. internal/broadcast destinations) to freedom
  3. If you build outbounds programmatically, set ob.Target via outbound.SetTarget(destination) before dispatching to freedom
Defensive patterns

Strategy: validation

Validate before calling

```go
ob := session.OutboundsFromContext(ctx)
tail := ob[len(ob)-1]
if !tail.Target.IsValid() {
    // route elsewhere / return 4xx before reaching freedom
}
```

Type guard

```go
func hasValidTarget(ctx context.Context) bool {
    obs := session.OutboundsFromContext(ctx)
    return len(obs) > 0 && obs[len(obs)-1].Target.IsValid()
}
```

Prevention

When it happens

Trigger: Routing/dispatcher hands freedom a session whose outbound.Target was never set — e.g. an inbound produced a connection with no parsed destination, or a custom dispatcher/chain created an Outbound without calling SetTarget. Calling freedom via a chain where the preceding hop failed to propagate the target also triggers it.

Common situations: Misconfigured routing rule that forwards opaque/internal traffic to freedom; a dokodemo/transparent inbound where the original destination could not be recovered (SO_ORIGINAL_DST missing); third-party outbound handlers that skip ob.Target assignment.

Related errors


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