XTLS/Xray-core · error
legacy nonIPQuery and blockTypes cannot be mixed with rules
Error message
legacy nonIPQuery and blockTypes cannot be mixed with rules
What it means
Thrown when an Xray DNS outbound config simultaneously declares the deprecated 'nonIPQuery'/'blockTypes' fields and the newer 'rules' array. The two mechanisms compile to overlapping rule sets, so the builder refuses to merge them and prints this error after the deprecation warning path detects both. It exists to force an explicit migration to 'rules'.
Source
Thrown at infra/conf/dns_proxy.go:97
}
if c.Port != 0 {
c.RewritePort = c.Port
}
config := &dns.Config{
RewriteServer: &net.Endpoint{
Network: c.RewriteNetwork.Build(),
Port: uint32(c.RewritePort),
},
UserLevel: c.UserLevel,
}
if c.RewriteAddress != nil {
config.RewriteServer.Address = c.RewriteAddress.Build()
}
// todo: remove legacy
if c.NonIPQuery != nil || c.BlockTypes != nil {
if c.Rules != nil {
return nil, errors.New("legacy nonIPQuery and blockTypes cannot be mixed with rules")
}
errors.PrintDeprecatedFeatureWarning(`"nonIPQuery" and "blockTypes"`, `"rules"`)
rules, err := c.buildLegacyDNSPolicy()
if err != nil {
return nil, err
}
config.Rule = rules
return config, nil
}
for _, r := range c.Rules {
rule, err := r.Build()
if err != nil {
return nil, err
}
config.Rule = append(config.Rule, rule)
}
View on GitHub (pinned to 7d214f8b09)
Solutions
- Delete "nonIPQuery" and "blockTypes" from the DNS outbound and express the same policy with "rules".
- Map legacy values: nonIPQuery "drop" -> rule action "drop" on the non-A/AAAA qtypes; "reject" -> action "return" with rcode 5; blockTypes -> a rule listing those qTypes.
- Keep only the legacy fields (remove "rules") if you cannot migrate yet — one or the other, never both.
Example fix
// before
"nonIPQuery": "drop",
"blockTypes": [255],
"rules": [{"action": "drop", "qType": [255]}]
// after
"rules": [
{"action": "drop", "qType": [255]},
{"action": "hijack", "qType": [1, 28]}
] Defensive patterns
Strategy: validation
Validate before calling
if (c.nonIPQuery !== undefined || c.blockTypes !== undefined) && Array.isArray(c.rules) && c.rules.length > 0 {
throw new Error('nonIPQuery/blockTypes cannot be mixed with rules; migrate to rules');
} Prevention
- Treat nonIPQuery/blockTypes as removed: delete them when adding "rules".
- Automate migration with a config lint rule that flags both present.
- Read Xray release notes when touching DNS config after upgrades.
When it happens
Trigger: A DNS outbound JSON containing e.g. "nonIPQuery": "drop" or "blockTypes": [255] together with a non-empty "rules": [...] in the same object. Checked at the top of DNSOutboundConfig.Build() before rules are compiled.
Common situations: Upgrading an old config to the rules syntax but leaving the legacy fields in place 'just in case'; merging example snippets from docs of different Xray versions.
Related errors
- unknown nonIPQuery: {}
- legacy blockTypes qType out of range: {}
- unknown action: {}
- rCode out of range: {}
- empty domains & empty resolvers
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/2ebca7cc04b3f4a3.
Report an issue: GitHub.