XTLS/Xray-core · error

invalid address

Error message

invalid address

What it means

Thrown by HostAddress.UnmarshalJSON in infra/conf/dns.go when a dns.hosts value is neither a single address string (Address unmarshal) nor an array of address strings. Hosts entries accept "domain": "ip" or "domain": ["ip1","ip2"]; any other JSON type hits the default branch.

Source

Thrown at infra/conf/dns.go:202

			return json.Marshal(h.addr)
		} else if h.addrs != nil {
			return json.Marshal(h.addrs)
		}
	}
	return nil, errors.New("unexpected config state")
}

// UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON
func (h *HostAddress) UnmarshalJSON(data []byte) error {
	addr := new(Address)
	var addrs []*Address
	switch {
	case json.Unmarshal(data, &addr) == nil:
		h.addr = addr
	case json.Unmarshal(data, &addrs) == nil:
		h.addrs = addrs
	default:
		return errors.New("invalid address")
	}
	return nil
}

type HostsWrapper struct {
	Hosts map[string]*HostAddress
}

func newHostMapping(ha *HostAddress) *dns.Config_HostMapping {
	if ha.addr != nil {
		if ha.addr.Family().IsDomain() {
			return &dns.Config_HostMapping{
				ProxiedDomain: ha.addr.Domain(),
			}
		}
		return &dns.Config_HostMapping{
			Ip: [][]byte{ha.addr.IP()},
		}

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Map each host to a string IP or domain: "hosts": {"example.com": "1.2.3.4"}
  2. For multiple targets use an array of strings: "hosts": {"example.com": ["1.2.3.4", "5.6.7.8"]}
  3. Do not include ports or nested objects in hosts values

Example fix

// before
"hosts": {"example.com": {"ip": "1.2.3.4"}}

// after
"hosts": {"example.com": "1.2.3.4"}
Defensive patterns

Strategy: type-guard

Validate before calling

func isHostAddressValue(v any) error {
    switch t := v.(type) {
    case string:
        return nil
    case []any:
        for _, e := range t {
            if _, ok := e.(string); !ok {
                return fmt.Errorf("host array entry %v is not a string", e)
            }
        }
        return nil
    }
    return errors.New("hosts value must be a string or array of strings")
}

Type guard

func isHostAddress(v any) bool {
    if _, ok := v.(string); ok {
        return true
    }
    arr, ok := v.([]any)
    if !ok {
        return false
    }
    for _, e := range arr {
        if _, isStr := e.(string); !isStr {
            return false
        }
    }
    return true
}

Try / catch

if err := json.Unmarshal(data, &ha); err != nil {
    if strings.Contains(err.Error(), "invalid address") {
        return fmt.Errorf("hosts value %s must be "ip" or ["ip1","ip2"]", data)
    }
    return err
}

Prevention

When it happens

Trigger: "hosts": {"example.com": 12345}, {"example.com": {"ip":"1.2.3.4"}}, or {"example.com": true}. Also nested arrays or mixed arrays where Address unmarshal of the array form fails.

Common situations: Adding a port to a hosts entry ("example.com": "1.2.3.4:80" parses but later address parsing of the combined string produces a domain-family address — different failure); putting objects meant for other DNS fields under hosts.

Related errors


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