XTLS/Xray-core · error

Failed to build "downloadSettings".

Error message

Failed to build "downloadSettings".

What it means

When "downloadSettings" is present and mode is not stream-one, SplitHTTPConfig.Build() calls DownloadSettings.Build() (a full StreamConfig build) and wraps any failure at transport_method.go:503-506. The base error identifies the nested failure: bad transport name, invalid transportSettings for the chosen download transport (tcp/kcp/ws/http/grpc etc.), invalid security settings, or invalid proxySettings.

Source

Thrown at infra/conf/transport_method.go:505

		SessionIDTable:       c.SessionIDTable,
		SessionIDLength:      newRangeConfig(c.SessionIDLength),
		Xmux: &splithttp.XmuxConfig{
			MaxConcurrency:   newRangeConfig(c.Xmux.MaxConcurrency),
			MaxConnections:   newRangeConfig(c.Xmux.MaxConnections),
			CMaxReuseTimes:   newRangeConfig(c.Xmux.CMaxReuseTimes),
			HMaxRequestTimes: newRangeConfig(c.Xmux.HMaxRequestTimes),
			HMaxReusableSecs: newRangeConfig(c.Xmux.HMaxReusableSecs),
			HKeepAlivePeriod: c.Xmux.HKeepAlivePeriod,
		},
	}

	if c.DownloadSettings != nil {
		if c.Mode == "stream-one" {
			return nil, errors.New(`Can not use "downloadSettings" in "stream-one" mode.`)
		}
		var err error
		if config.DownloadSettings, err = c.DownloadSettings.Build(); err != nil {
			return nil, errors.New(`Failed to build "downloadSettings".`).Base(err)
		}
	}

	return config, nil
}

func roomSize(tableSize int, min, max int32) *big.Int {
	base := big.NewInt(int64(tableSize))
	sum := new(big.Int)
	term := new(big.Int)
	for k := min; k <= max; k++ {
		term.Exp(base, big.NewInt(int64(k)), nil)
		sum.Add(sum, term)
	}
	return sum
}

type KCPConfig struct {

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Read the base (chained) error — it is the inner StreamConfig build failure and names the real problem
  2. Fix the nested transportSettings/tlsSettings per that inner error's documentation
  3. Ensure "transport" inside downloadSettings.transportSettings is a registered stream transport (tcp, rawtcp, ws, http, h2, grpc, gun, splithttp, kcp...)
  4. Simplify: omit downloadSettings to use the same transport for both directions while testing

Example fix

// before
"downloadSettings": { "transportSettings": { "transport": "h3" } }
// after
"downloadSettings": { "transportSettings": { "transport": "http", "transportSettings": { "host": "dl.example.com", "path": /dl" } } }
Defensive patterns

Strategy: try-catch

Try / catch

// Go: wrap and unwrap the chained base error to reach the inner StreamConfig failure
if _, err := cfg.Build(); err != nil {
	if strings.Contains(err.Error(), `Failed to build "downloadSettings"`) {
		// err chain's Base holds the nested cause; log the full chain
		log.Printf("nested download transport invalid: %v", err)
	}
	return err
}

Prevention

When it happens

Trigger: "downloadSettings": {"transportSettings": {"transport": "h2"}} where h2 is not a registered transport; or a tcp downloadSettings with an invalid header block (reuses error 400/401 logic); or "security": "tls" with a malformed tlsSettings object.

Common situations: Splitting up/down transports across CDNs and typo-ing the download transport type; downloadSettings copied from an outbound streamSettings retaining fields invalid in this position; version drift where a transport was renamed.

Related errors


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