{"record":{"id":"85a426071e7b56b5","repo":"XTLS/Xray-core","slug":"unexpected-query-strategy","errorCode":null,"errorMessage":"unexpected query strategy ","messagePattern":"unexpected query strategy ","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/dns/dns.go","lineNumber":81,"sourceCode":"\t\t\tIPv4Enable: true,\n\t\t\tIPv6Enable: true,\n\t\t\tFakeEnable: false,\n\t\t}\n\t\tcheckSystem = true\n\tcase QueryStrategy_USE_IP4:\n\t\tipOption = dns.IPOption{\n\t\t\tIPv4Enable: true,\n\t\t\tIPv6Enable: false,\n\t\t\tFakeEnable: false,\n\t\t}\n\tcase QueryStrategy_USE_IP6:\n\t\tipOption = dns.IPOption{\n\t\t\tIPv4Enable: false,\n\t\t\tIPv6Enable: true,\n\t\t\tFakeEnable: false,\n\t\t}\n\tdefault:\n\t\treturn nil, errors.New(\"unexpected query strategy \", config.QueryStrategy)\n\t}\n\n\thosts, err := NewStaticHosts(config.StaticHosts)\n\tif err != nil {\n\t\treturn nil, errors.New(\"failed to create hosts\").Base(err)\n\t}\n\n\tdefaultTag := config.Tag\n\tif len(config.Tag) == 0 {\n\t\tdefaultTag = generateRandomTag()\n\t}\n\n\tclients := make([]*Client, 0, len(config.NameServer))\n\tmatcherInfos := make([]*DomainMatcherInfo, 0)\n\teffectiveRules := make([]*geodata.DomainRule, 0)\n\n\tfor _, ns := range config.NameServer {\n\t\tclientIdx := len(clients)","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/app/dns/dns.go#L63-L99","documentation":"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.","triggerScenarios":"Calling writePaddingTurn/writePaddingTurnWithSleep directly (bypassing runPaddingSchedule validation) with a malformed startDelay; or rand.Reader failing (entropy exhaustion, heavily restricted environments).","commonSituations":"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.","solutions":["Fix the delay range: min >= 0 and max >= min","Prefer runPaddingSchedule over direct writePaddingTurn calls so validation runs first","If caused by rand.Reader failure, check OS entropy availability (e.g. wait for the entropy source in minimal containers)"],"exampleFix":"// before\nstartDelay: paddingDelayRange{min: 50 * time.Millisecond, max: 10 * time.Millisecond}\n// after\nstartDelay: paddingDelayRange{min: 10 * time.Millisecond, max: 50 * time.Millisecond}","handlingStrategy":"validation","validationCode":"func validDelay(d paddingDelayRange) bool {\n    return d.min >= 0 && d.max >= d.min\n}\n// check turn.startDelay and every variant delay before writing","typeGuard":null,"tryCatchPattern":"if err := writePaddingTurn(w, turn, prefix); err != nil {\n    if strings.Contains(err.Error(), \"select padding start delay\") {\n        // config bug in delay range or entropy failure; do not retry unchanged\n    }\n    return err\n}","preventionTips":["Route turns through runPaddingSchedule for up-front delay validation","Order delay bounds at config parse time (swap if min > max)","Monitor rand.Reader health on entropy-poor hosts"],"tags":["padding","delay","crypto-rand","xmc"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}