{"record":{"id":"ae998d279166de0c","repo":"XTLS/Xray-core","slug":"invalid-geodata-asset-url","errorCode":null,"errorMessage":"invalid geodata asset url: ","messagePattern":"invalid geodata asset url: ","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/geodata.go","lineNumber":20,"sourceCode":"\nimport (\n\t\"net/url\"\n\n\t\"github.com/robfig/cron/v3\"\n\t\"github.com/xtls/xray-core/app/geodata\"\n\t\"github.com/xtls/xray-core/common/errors\"\n\t\"github.com/xtls/xray-core/common/platform/filesystem\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\ntype GeodataAssetConfig struct {\n\tURL  string `json:\"url\"`\n\tFile string `json:\"file\"`\n}\n\nfunc (c *GeodataAssetConfig) Build() (*geodata.Asset, error) {\n\tif err := validateHTTPS(c.URL); err != nil {\n\t\treturn nil, errors.New(\"invalid geodata asset url: \", c.URL).Base(err)\n\t}\n\tif _, err := filesystem.StatAsset(c.File); err != nil {\n\t\treturn nil, errors.New(\"invalid geodata asset file: \", c.File).Base(err)\n\t}\n\treturn &geodata.Asset{\n\t\tUrl:  c.URL,\n\t\tFile: c.File,\n\t}, nil\n}\n\nfunc validateHTTPS(s string) error {\n\tu, err := url.ParseRequestURI(s)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif u.Scheme != \"https\" || u.Host == \"\" {\n\t\treturn errors.New(\"scheme must be https\")\n\t}","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/geodata.go#L2-L38","documentation":"Thrown by GeodataAssetConfig.Build when the asset's url field fails validateHTTPS, i.e. it cannot be parsed as a request URI or its scheme is not https / host is empty. Geodata assets are downloaded over HTTPS only, so any malformed or non-HTTPS URL is rejected before the asset table is built. The underlying parse/scheme error is attached as the base cause.","triggerScenarios":"Configuring geodata.assets[].url as an http:// URL, an ftp:// URL, a scheme-less host like 'geosite.example.com', or a string that fails url.ParseRequestURI. Error 285 ('scheme must be https') is the sibling produced when parsing succeeds but the scheme check fails.","commonSituations":"Pointing at a mirror that only serves plain http; forgetting the https:// scheme; using a GitHub raw URL with a typo; copying an asset URL from older configs that predate the HTTPS enforcement.","solutions":["Use a URL starting with https:// and including a host, e.g. https://example.com/dat/geosite.dat","If the mirror only supports http, host the file locally and reference it via the file field with an https-capable mirror, or set up an https endpoint","Check for typos, stray whitespace, or missing scheme in the url string"],"exampleFix":"// before\n{ \"url\": \"http://mirror.example/geosite.dat\", \"file\": \"geosite.dat\" }\n// after\n{ \"url\": \"https://mirror.example/geosite.dat\", \"file\": \"geosite.dat\" }","handlingStrategy":"validation","validationCode":"// Validate geodata asset URL before building config\nu, err := url.ParseRequestURI(asset.URL)\nif err != nil || u.Scheme != \"https\" || u.Host == \"\" {\n\treturn fmt.Errorf(\"asset url %q must be a valid https URL\", asset.URL)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Normalize all geodata mirror URLs to https:// at config generation time","Test mirrors with curl -I https://... before committing them to configs"],"tags":["xray","config","geodata","url","validation"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}