XTLS/Xray-core · error

Interval must be at least 5

Error message

Interval must be at least 5

What it means

Range check on the UDP hop interval under finalMask.quicParams.udpHop.interval: a non-zero From or To below 5 is rejected (0 means unset and is allowed). Units follow the config schema (seconds). It exists to prevent hop intervals so short they would thrash connections.

Source

Thrown at infra/conf/transport_internet.go:257

				return nil, errors.New("BrutalUp must be at least 65536 bytes per second")
			}
			if down > 0 && down < 65536 {
				return nil, errors.New("BrutalDown must be at least 65536 bytes per second")
			}

			c.FinalMask.QuicParams.Congestion = strings.ToLower(c.FinalMask.QuicParams.Congestion)
			switch c.FinalMask.QuicParams.Congestion {
			case "", "brutal", "reno", "bbr":
			case "force-brutal":
				if up == 0 {
					return nil, errors.New("force-brutal requires up")
				}
			default:
				return nil, errors.New("unknown congestion control: ", c.FinalMask.QuicParams.Congestion, ", valid values: reno, bbr, brutal, force-brutal")
			}

			if (c.FinalMask.QuicParams.UdpHop.Interval.From != 0 && c.FinalMask.QuicParams.UdpHop.Interval.From < 5) || (c.FinalMask.QuicParams.UdpHop.Interval.To != 0 && c.FinalMask.QuicParams.UdpHop.Interval.To < 5) {
				return nil, errors.New("Interval must be at least 5")
			}

			if c.FinalMask.QuicParams.InitStreamReceiveWindow > 0 && c.FinalMask.QuicParams.InitStreamReceiveWindow < 16384 {
				return nil, errors.New("InitStreamReceiveWindow must be at least 16384")
			}
			if c.FinalMask.QuicParams.MaxStreamReceiveWindow > 0 && c.FinalMask.QuicParams.MaxStreamReceiveWindow < 16384 {
				return nil, errors.New("MaxStreamReceiveWindow must be at least 16384")
			}
			if c.FinalMask.QuicParams.InitConnectionReceiveWindow > 0 && c.FinalMask.QuicParams.InitConnectionReceiveWindow < 16384 {
				return nil, errors.New("InitConnectionReceiveWindow must be at least 16384")
			}
			if c.FinalMask.QuicParams.MaxConnectionReceiveWindow > 0 && c.FinalMask.QuicParams.MaxConnectionReceiveWindow < 16384 {
				return nil, errors.New("MaxConnectionReceiveWindow must be at least 16384")
			}
			if c.FinalMask.QuicParams.MaxIdleTimeout != 0 && (c.FinalMask.QuicParams.MaxIdleTimeout < 4 || c.FinalMask.QuicParams.MaxIdleTimeout > 120) {
				return nil, errors.New("MaxIdleTimeout must be between 4 and 120")
			}
			if c.FinalMask.QuicParams.KeepAlivePeriod != 0 && (c.FinalMask.QuicParams.KeepAlivePeriod < 2 || c.FinalMask.QuicParams.KeepAlivePeriod > 60) {

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Raise both from and to to at least 5 (or remove them for the default).
  2. Keep from <= to so the range is meaningful.
  3. Confirm the field's unit in the config docs before tuning.

Example fix

// before
"udpHop": { "interval": { "from": 1, "to": 3 } }
// after
"udpHop": { "interval": { "from": 5, "to": 10 } }
Defensive patterns

Strategy: validation

Validate before calling

func udpHopIntervalOK(qp map[string]any) bool {
    uh, _ := qp["udpHop"].(map[string]any)
    iv, _ := uh["interval"].(map[string]any)
    for _, k := range []string{"from", "to"} {
        if v, ok := iv[k].(float64); ok && v != 0 && v < 5 { return false }
    }
    return true
}

Prevention

When it happens

Trigger: "udpHop": { "interval": { "from": 2 } } or any non-zero endpoint below 5.

Common situations: Tuning hop intervals down for faster rotation without knowing the floor; setting milliseconds where seconds are expected (making values tiny); copying aggressive values from other tools.

Related errors


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