XTLS/Xray-core · error

redirected to non-https URL:

Error message

redirected to non-https URL: 

What it means

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.

Source

Thrown at app/geodata/download.go:112

				DialTLSContext: func(ctx context.Context, network string, address string, cfg *tls.Config) (net.Conn, error) {
					conn, err := dial(ctx, network, address)
					if err != nil {
						return nil, err
					}
					host, _, _ := net.SplitHostPort(address)
					tlsConn := utls.UClient(conn, &utls.Config{ServerName: host}, utls.HelloChrome_Auto)
					handshakeCtx, cancel := context.WithTimeout(ctx, idleTimeout)
					defer cancel()
					if err := tlsConn.HandshakeContext(handshakeCtx); err != nil {
						conn.Close()
						return nil, err
					}
					return tlsConn, nil
				},
			},
			CheckRedirect: func(req *http.Request, via []*http.Request) error {
				if req.URL.Scheme != "https" {
					return errors.New("redirected to non-https URL: ", req.URL.String())
				}
				if len(via) >= 10 {
					return errors.New("stopped after 10 redirects")
				}
				return nil
			},
		}
	} else {
		return &http.Client{
			Transport: &http.Transport{
				Proxy:                 nil,
				DisableKeepAlives:     true,
				DialContext:           dial,
				ResponseHeaderTimeout: idleTimeout,
			},
			CheckRedirect: func(req *http.Request, via []*http.Request) error {
				if req.URL.Scheme != "https" {
					return errors.New("redirected to non-https URL: ", req.URL.String())

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Use a mirror that serves and redirects entirely over https (official GitHub raw / jsdelivr)
  2. If the http endpoint is trusted, configure the asset with an explicit http:// URL so the plain client branch (no https enforcement) is used
  3. Check for a captive portal or middlebox rewriting the redirect by curl -I-ing the asset URL
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check the redirect chain stays on https before relying on the downloader:
// (run in CI or a healthcheck)
// curl -sIL <asset-url> | grep -i '^location:' — every hop must be https://

Try / catch

if err := d.download(assets); err != nil {
    if strings.Contains(err.Error(), "redirected to non-https URL") {
        // switch asset URL to a fully-https mirror
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/bd51b40b86cfb020. Report an issue: GitHub.