XTLS/Xray-core · error

unsupported domain strategy: {}

Error message

unsupported domain strategy: {}

What it means

Thrown by freedom outbound Build() when the (effective) domainStrategy string is not one of the supported keywords. After resolving targetStrategy (from the outbound's setting or the global one), the switch accepts asis/useip/useipv4/useipv6/useip4/useip6/forceip/forceipv4/forceipv6/forceipv4v6/forceipv6v4 (case-insensitive); anything else hits the default branch.

Source

Thrown at infra/conf/freedom.go:90

		config.DomainStrategy = internet.DomainStrategy_USE_IP4
	case "useipv6":
		config.DomainStrategy = internet.DomainStrategy_USE_IP6
	case "useipv4v6":
		config.DomainStrategy = internet.DomainStrategy_USE_IP46
	case "useipv6v4":
		config.DomainStrategy = internet.DomainStrategy_USE_IP64
	case "forceip":
		config.DomainStrategy = internet.DomainStrategy_FORCE_IP
	case "forceipv4":
		config.DomainStrategy = internet.DomainStrategy_FORCE_IP4
	case "forceipv6":
		config.DomainStrategy = internet.DomainStrategy_FORCE_IP6
	case "forceipv4v6":
		config.DomainStrategy = internet.DomainStrategy_FORCE_IP46
	case "forceipv6v4":
		config.DomainStrategy = internet.DomainStrategy_FORCE_IP64
	default:
		return nil, errors.New("unsupported domain strategy: ", targetStrategy)
	}

	if c.Fragment != nil {
		config.Fragment = new(freedom.Fragment)

		switch strings.ToLower(c.Fragment.Packets) {
		case "tlshello":
			// TLS Hello Fragmentation (into multiple handshake messages)
			config.Fragment.PacketsFrom = 0
			config.Fragment.PacketsTo = 1
		case "":
			// TCP Segmentation (all packets)
			config.Fragment.PacketsFrom = 0
			config.Fragment.PacketsTo = 0
		default:
			// TCP Segmentation (range)
			from, to, err := ParseRangeString(c.Fragment.Packets)
			if err != nil {

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Use one of the exact tokens: "AsIs", "UseIP", "UseIPv4", "UseIPv6", "UseIP4", "UseIP6", "ForceIP", "ForceIPv4", "ForceIPv6", "ForceIPv4v6", "ForceIPv6v4" (case-insensitive).
  2. If translating from sing-box: ipv4_only -> UseIPv4, ipv6_only -> UseIPv6, prefer_ipv4 -> UseIPv4/UseIP4.
  3. Check the global "domainStrategy" too — an invalid global value surfaces here when the outbound does not override it.

Example fix

// before
"domainStrategy": "use_ipv4"

// after
"domainStrategy": "UseIPv4"
Defensive patterns

Strategy: validation

Validate before calling

var validStrategies = map[string]bool{
    "asis": true, "useip": true, "useipv4": true, "useipv6": true,
    "useip4": true, "useip6": true, "forceip": true, "forceipv4": true,
    "forceipv6": true, "forceipv4v6": true, "forceipv6v4": true,
}
if !validStrategies[strings.ToLower(strategy)] {
    return fmt.Errorf("unsupported domain strategy %q", strategy)
}

Prevention

When it happens

Trigger: "domainStrategy": "use_ip" (underscore instead of concatenation), "ForceIP", "prefer_ipv4", or any non-listed synonym in a freedom outbound or the global settings; also triggered when the strategy falls back to the global value and that global value is invalid.

Common situations: Copy-pasting strategy names from sing-box or Clash configs (they use different spellings like 'ipv4_only'); upgrading from configs written against older docs; assuming underscores are allowed.

Related errors


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