XTLS/Xray-core · error

unknown nonIPQuery: {}

Error message

unknown nonIPQuery: {}

What it means

Thrown while compiling the deprecated 'nonIPQuery' setting of a DNS outbound into internal rules: the mode string is not one of the accepted values. buildLegacyDNSPolicy() accepts only "" (defaults to reject), "reject", "drop", and "skip"; anything else is rejected. This runs only on the legacy code path (nonIPQuery/blockTypes present without 'rules').

Source

Thrown at infra/conf/dns_proxy.go:130

		}
		config.Rule = append(config.Rule, rule)
	}

	return config, nil
}

// todo: remove legacy
func (c *DNSOutboundConfig) buildLegacyDNSPolicy() ([]*dns.DNSRuleConfig, error) {
	rules := make([]*dns.DNSRuleConfig, 0, 3)

	mode := "reject"
	if c.NonIPQuery != nil && *c.NonIPQuery != "" {
		mode = *c.NonIPQuery
	}
	switch mode {
	case "", "reject", "drop", "skip":
	default:
		return nil, errors.New("unknown nonIPQuery: ", mode)
	}

	if c.BlockTypes != nil && len(*c.BlockTypes) > 0 {
		rule := &dns.DNSRuleConfig{Action: dns.RuleAction_Drop}
		if mode == "reject" {
			rule.Action = dns.RuleAction_Return
			rule.RCode = 5
		}
		for _, qType := range *c.BlockTypes {
			if qType < 0 || qType > 65535 {
				return nil, errors.New("legacy blockTypes qType out of range: ", qType)
			}
			rule.QType = append(rule.QType, qType)
		}
		rules = append(rules, rule)
	}

	{

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Set "nonIPQuery" to "reject", "drop", "skip", or remove it entirely (default is reject).
  2. Prefer migrating to the "rules" array, which supersedes nonIPQuery and gives per-qType control.
  3. Check spelling/case: values are matched literally after the nil/empty default, so "Drop" works via strings equality? No — match is exact lowercase; use lowercase values.

Example fix

// before
"nonIPQuery": "block"

// after
"nonIPQuery": "drop"
Defensive patterns

Strategy: validation

Validate before calling

var validNonIPQuery = map[string]bool{"": true, "reject": true, "drop": true, "skip": true}

if c.NonIPQuery != nil && !validNonIPQuery[strings.ToLower(*c.NonIPQuery)] {
    return fmt.Errorf("unknown nonIPQuery %q", *c.NonIPQuery)
}

Prevention

When it happens

Trigger: A DNS outbound with "nonIPQuery": "allow" or "block" or any word other than reject/drop/skip, while not using the "rules" array. The switch default branch fires immediately.

Common situations: Guessing allowed values instead of checking docs; configs ported from tools whose semantics differ (e.g. dnsmasq 'refuse', AdGuard 'refused').

Related errors


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