{"record":{"id":"3d862df83a01c352","repo":"XTLS/Xray-core","slug":"empty-domains-empty-resolvers","errorCode":null,"errorMessage":"empty domains & empty resolvers","messagePattern":"empty domains & empty resolvers","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/transport_finalmask.go","lineNumber":708,"sourceCode":"\t\tPaddingMin:   paddingMin,\n\t\tPaddingMax:   paddingMax,\n\t}, nil\n}\n\ntype Xdns struct {\n\tDomain json.RawMessage `json:\"domain\"`\n\n\tDomains   []string `json:\"domains\"`\n\tResolvers []string `json:\"resolvers\"`\n}\n\nfunc (c *Xdns) Build() (proto.Message, error) {\n\tif c.Domain != nil {\n\t\treturn nil, errors.PrintRemovedFeatureError(\"domain\", \"domains(server) & resolvers(client)\")\n\t}\n\n\tif len(c.Domains) == 0 && len(c.Resolvers) == 0 {\n\t\treturn nil, errors.New(\"empty domains & empty resolvers\")\n\t}\n\n\tfor _, r := range c.Resolvers {\n\t\tif !strings.Contains(r, \"+udp://\") {\n\t\t\treturn nil, errors.New(\"invalid resolver \", r)\n\t\t}\n\t}\n\n\treturn &xdns.Config{\n\t\tDomains:   c.Domains,\n\t\tResolvers: c.Resolvers,\n\t}, nil\n}\n\ntype XMC struct {\n\tHostname string       `json:\"hostname\"`\n\tProfiles []XMCProfile `json:\"profiles\"`\n\tPassword string       `json:\"password\"`","sourceCodeStart":690,"sourceCodeEnd":726,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/transport_finalmask.go#L690-L726","documentation":"Thrown by Xdns.Build() when the xdns DNS-routing config declares neither 'domains' nor 'resolvers'. The builder requires at least one of the two lists so the module has something to act on; a completely empty object is rejected. Note that a legacy top-level 'domain' key is also rejected separately as a removed feature.","triggerScenarios":"Adding an xdns transport block with only unrelated fields, e.g. {} or {\"domains\": [], \"resolvers\": []}, produces this error during Build(). Also hit when JSON keys are misspelled (e.g. \"domain\" instead of \"domains\") so both slices decode empty.","commonSituations":"Enabling xdns without deciding server-side domains or client-side resolvers; typos in field names; migrating from the removed singular 'domain' field and leaving the object empty.","solutions":["Populate 'domains' (server side) or 'resolvers' (client side) with at least one entry.","Remove the xdns block entirely if you did not intend to enable it.","Check for the removed legacy 'domain' key and migrate it to 'domains'/'resolvers'."],"exampleFix":"// before\n\"transport\": { \"xdns\": {} }\n// after\n\"transport\": { \"xdns\": { \"resolvers\": [\"8.8.8.8+udp://\"] } }","handlingStrategy":"validation","validationCode":"if len(xdnsCfg.Domains) == 0 && len(xdnsCfg.Resolvers) == 0 {\n    return fmt.Errorf(\"xdns block is empty: supply domains or resolvers\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never emit an xdns object without at least one of domains/resolvers.","Use exact plural field names; the singular 'domain' key is removed.","Fail fast in config generators when optional modules decode to zero-value."],"tags":["go","xray","config","validation","dns"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}