{"record":{"id":"ca0a2b416bf5e8cf","repo":"XTLS/Xray-core","slug":"substr-in-dotless-rule-should-not-contain-a-dot","errorCode":null,"errorMessage":"substr in dotless rule should not contain a dot","messagePattern":"substr in dotless rule should not contain a dot","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/geodata/rule_parser.go","lineNumber":254,"sourceCode":"\t\tdomain.Value = rule[7:]\n\n\tcase strings.HasPrefix(rule, \"full:\"):\n\t\tdomain.Type = Domain_Full\n\t\tdomain.Value = rule[5:]\n\n\tcase strings.HasPrefix(rule, \"keyword:\"):\n\t\tdomain.Type = Domain_Substr\n\t\tdomain.Value = rule[8:]\n\n\tcase strings.HasPrefix(rule, \"dotless:\"):\n\t\tdomain.Type = Domain_Regex\n\t\tswitch substr := rule[8:]; {\n\t\tcase substr == \"\":\n\t\t\tdomain.Value = \"^[^.]*$\"\n\t\tcase !strings.Contains(substr, \".\"):\n\t\t\tdomain.Value = \"^[^.]*\" + substr + \"[^.]*$\"\n\t\tdefault:\n\t\t\treturn nil, errors.New(\"substr in dotless rule should not contain a dot\")\n\t\t}\n\n\tdefault:\n\t\tdomain.Type = defaultType\n\t\tdomain.Value = rule\n\t}\n\n\treturn &DomainRule_Custom{\n\t\tCustom: domain,\n\t}, nil\n}\n","sourceCodeStart":236,"sourceCodeEnd":266,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/common/geodata/rule_parser.go#L236-L266","documentation":"The 'dotless:' domain rule builds a regex '^[^.]*SUBSTR[^.]*$' matching single-label hostnames containing SUBSTR. Because the regex excludes dots, a SUBSTR containing '.' can never match and is rejected immediately as a configuration contradiction.","triggerScenarios":"Domain rule \"dotless:example.com\" (or any value containing a dot) — invalid by construction.","commonSituations":"Misunderstanding dotless matching: developers try to use dotless: for suffix matching instead of 'domain:'.","solutions":["For suffix/domain matching use \"domain:example.com\"; for exact host use \"full:example.com\".","Keep dotless: values dot-free, e.g. \"dotless:internal\" to match hostnames like 'db-internal'."],"exampleFix":"// before\n\"domain\": [\"dotless:example.com\"]\n\n// after\n\"domain\": [\"domain:example.com\"]","handlingStrategy":"validation","validationCode":"if strings.HasPrefix(r, \"dotless:\") && strings.Contains(r[8:], \".\") {\n    return fmt.Errorf(\"%q: dotless value must not contain a dot; use domain: instead\", r)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reserve dotless: for single-label matching; use domain:/full: for dotted names."],"tags":["geodata","domain-rule","dotless","regex","xray"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}