{"record":{"id":"2ebca7cc04b3f4a3","repo":"XTLS/Xray-core","slug":"legacy-nonipquery-and-blocktypes-cannot-be-mixed-w","errorCode":null,"errorMessage":"legacy nonIPQuery and blockTypes cannot be mixed with rules","messagePattern":"legacy nonIPQuery and blockTypes cannot be mixed with rules","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/dns_proxy.go","lineNumber":97,"sourceCode":"\t}\n\tif c.Port != 0 {\n\t\tc.RewritePort = c.Port\n\t}\n\tconfig := &dns.Config{\n\t\tRewriteServer: &net.Endpoint{\n\t\t\tNetwork: c.RewriteNetwork.Build(),\n\t\t\tPort:    uint32(c.RewritePort),\n\t\t},\n\t\tUserLevel: c.UserLevel,\n\t}\n\tif c.RewriteAddress != nil {\n\t\tconfig.RewriteServer.Address = c.RewriteAddress.Build()\n\t}\n\n\t// todo: remove legacy\n\tif c.NonIPQuery != nil || c.BlockTypes != nil {\n\t\tif c.Rules != nil {\n\t\t\treturn nil, errors.New(\"legacy nonIPQuery and blockTypes cannot be mixed with rules\")\n\t\t}\n\t\terrors.PrintDeprecatedFeatureWarning(`\"nonIPQuery\" and \"blockTypes\"`, `\"rules\"`)\n\t\trules, err := c.buildLegacyDNSPolicy()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.Rule = rules\n\t\treturn config, nil\n\t}\n\n\tfor _, r := range c.Rules {\n\t\trule, err := r.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.Rule = append(config.Rule, rule)\n\t}\n","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/dns_proxy.go#L79-L115","documentation":"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'.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n\"nonIPQuery\": \"drop\",\n\"blockTypes\": [255],\n\"rules\": [{\"action\": \"drop\", \"qType\": [255]}]\n\n// after\n\"rules\": [\n  {\"action\": \"drop\", \"qType\": [255]},\n  {\"action\": \"hijack\", \"qType\": [1, 28]}\n]","handlingStrategy":"validation","validationCode":"if (c.nonIPQuery !== undefined || c.blockTypes !== undefined) && Array.isArray(c.rules) && c.rules.length > 0 {\n    throw new Error('nonIPQuery/blockTypes cannot be mixed with rules; migrate to rules');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["go","xray","dns","config","deprecated","migration"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}