XTLS/Xray-core · error

unexpected query strategy

Error message

unexpected query strategy 

What it means

While writing a padding turn, writePaddingTurnWithBuffer draws the turn's start delay via randomPaddingDelay(turn.startDelay); this error wraps that failure. Two sub-causes exist: the delay range is invalid (min < 0 or max < min), or crypto/rand.Int failed at the OS level. The invalid-range cause is normally caught earlier by validatePaddingSchedule, so in practice this surfaces when a lower-level write API is called on an unvalidated turn or the system entropy source errors.

Source

Thrown at app/dns/dns.go:81

			IPv4Enable: true,
			IPv6Enable: true,
			FakeEnable: false,
		}
		checkSystem = true
	case QueryStrategy_USE_IP4:
		ipOption = dns.IPOption{
			IPv4Enable: true,
			IPv6Enable: false,
			FakeEnable: false,
		}
	case QueryStrategy_USE_IP6:
		ipOption = dns.IPOption{
			IPv4Enable: false,
			IPv6Enable: true,
			FakeEnable: false,
		}
	default:
		return nil, errors.New("unexpected query strategy ", config.QueryStrategy)
	}

	hosts, err := NewStaticHosts(config.StaticHosts)
	if err != nil {
		return nil, errors.New("failed to create hosts").Base(err)
	}

	defaultTag := config.Tag
	if len(config.Tag) == 0 {
		defaultTag = generateRandomTag()
	}

	clients := make([]*Client, 0, len(config.NameServer))
	matcherInfos := make([]*DomainMatcherInfo, 0)
	effectiveRules := make([]*geodata.DomainRule, 0)

	for _, ns := range config.NameServer {
		clientIdx := len(clients)

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Fix the delay range: min >= 0 and max >= min
  2. Prefer runPaddingSchedule over direct writePaddingTurn calls so validation runs first
  3. If caused by rand.Reader failure, check OS entropy availability (e.g. wait for the entropy source in minimal containers)

Example fix

// before
startDelay: paddingDelayRange{min: 50 * time.Millisecond, max: 10 * time.Millisecond}
// after
startDelay: paddingDelayRange{min: 10 * time.Millisecond, max: 50 * time.Millisecond}
Defensive patterns

Strategy: validation

Validate before calling

func validDelay(d paddingDelayRange) bool {
    return d.min >= 0 && d.max >= d.min
}
// check turn.startDelay and every variant delay before writing

Try / catch

if err := writePaddingTurn(w, turn, prefix); err != nil {
    if strings.Contains(err.Error(), "select padding start delay") {
        // config bug in delay range or entropy failure; do not retry unchanged
    }
    return err
}

Prevention

When it happens

Trigger: Calling writePaddingTurn/writePaddingTurnWithSleep directly (bypassing runPaddingSchedule validation) with a malformed startDelay; or rand.Reader failing (entropy exhaustion, heavily restricted environments).

Common situations: Unit tests or custom transport code invoking the write path with hand-built turns; containers/VMs with depleted entropy at boot; a delay range built from config parsing that allows negative durations.

Related errors


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