{"record":{"id":"bd51b40b86cfb020","repo":"XTLS/Xray-core","slug":"redirected-to-non-https-url","errorCode":null,"errorMessage":"redirected to non-https URL: ","messagePattern":"redirected to non-https URL: ","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/geodata/download.go","lineNumber":112,"sourceCode":"\t\t\t\tDialTLSContext: func(ctx context.Context, network string, address string, cfg *tls.Config) (net.Conn, error) {\n\t\t\t\t\tconn, err := dial(ctx, network, address)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t}\n\t\t\t\t\thost, _, _ := net.SplitHostPort(address)\n\t\t\t\t\ttlsConn := utls.UClient(conn, &utls.Config{ServerName: host}, utls.HelloChrome_Auto)\n\t\t\t\t\thandshakeCtx, cancel := context.WithTimeout(ctx, idleTimeout)\n\t\t\t\t\tdefer cancel()\n\t\t\t\t\tif err := tlsConn.HandshakeContext(handshakeCtx); err != nil {\n\t\t\t\t\t\tconn.Close()\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t}\n\t\t\t\t\treturn tlsConn, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tCheckRedirect: func(req *http.Request, via []*http.Request) error {\n\t\t\t\tif req.URL.Scheme != \"https\" {\n\t\t\t\t\treturn errors.New(\"redirected to non-https URL: \", req.URL.String())\n\t\t\t\t}\n\t\t\t\tif len(via) >= 10 {\n\t\t\t\t\treturn errors.New(\"stopped after 10 redirects\")\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t},\n\t\t}\n\t} else {\n\t\treturn &http.Client{\n\t\t\tTransport: &http.Transport{\n\t\t\t\tProxy:                 nil,\n\t\t\t\tDisableKeepAlives:     true,\n\t\t\t\tDialContext:           dial,\n\t\t\t\tResponseHeaderTimeout: idleTimeout,\n\t\t\t},\n\t\t\tCheckRedirect: func(req *http.Request, via []*http.Request) error {\n\t\t\t\tif req.URL.Scheme != \"https\" {\n\t\t\t\t\treturn errors.New(\"redirected to non-https URL: \", req.URL.String())","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/app/geodata/download.go#L94-L130","documentation":"CheckRedirect hook on the HTTPS geodata client (http2.Transport branch): every redirect target must stay on https. If a redirect response points at an http:// URL, the client aborts with this error, which includes the offending URL.","triggerScenarios":"The geodata asset URL (or any redirect in its chain) responds with a Location header whose scheme is http rather than https, while downloading via the HTTPS client.","commonSituations":"A geodata mirror that redirects to a plain-http CDN; an intercepted/MITM network that rewrites redirects; a manually configured asset URL on a server that downgrades to http for large files.","solutions":["Use a mirror that serves and redirects entirely over https (official GitHub raw / jsdelivr)","If the http endpoint is trusted, configure the asset with an explicit http:// URL so the plain client branch (no https enforcement) is used","Check for a captive portal or middlebox rewriting the redirect by curl -I-ing the asset URL"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-check the redirect chain stays on https before relying on the downloader:\n// (run in CI or a healthcheck)\n// curl -sIL <asset-url> | grep -i '^location:' — every hop must be https://","typeGuard":null,"tryCatchPattern":"if err := d.download(assets); err != nil {\n    if strings.Contains(err.Error(), \"redirected to non-https URL\") {\n        // switch asset URL to a fully-https mirror\n    }\n}","preventionTips":["Use https-only mirrors for geodata assets","Verify redirect chains after changing any asset URL","Watch for middleboxes on hostile networks rewriting redirects to http"],"tags":["network","geodata","https","redirect","download"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}