{"record":{"id":"a6beb92a746ae444","repo":"XTLS/Xray-core","slug":"failed-to-create-expected-ip-matcher","errorCode":null,"errorMessage":"failed to create expected ip matcher","messagePattern":"failed to create expected ip matcher","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/dns/nameserver.go","lineNumber":116,"sourceCode":"\tupdateRules func(bool),\n) (*Client, error) {\n\tclient := &Client{}\n\terr := core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) error {\n\t\t// Create a new server for each client for now\n\t\tserver, err := NewServer(ctx, ns.Address.AsDestination(), dispatcher, disableCache, serveStale, serveExpiredTTL, clientIP)\n\t\tif err != nil {\n\t\t\treturn errors.New(\"failed to create nameserver\").Base(err).AtWarning()\n\t\t}\n\n\t\t_, isLocalDNS := server.(*LocalNameServer)\n\t\tupdateRules(isLocalDNS)\n\n\t\t// Establish expected IPs\n\t\tvar expectedMatcher geodata.IPMatcher\n\t\tif len(ns.ExpectedIp) > 0 {\n\t\t\texpectedMatcher, err = geodata.IPReg.BuildIPMatcher(ns.ExpectedIp)\n\t\t\tif err != nil {\n\t\t\t\treturn errors.New(\"failed to create expected ip matcher\").Base(err).AtWarning()\n\t\t\t}\n\t\t}\n\n\t\t// Establish unexpected IPs\n\t\tvar unexpectedMatcher geodata.IPMatcher\n\t\tif len(ns.UnexpectedIp) > 0 {\n\t\t\tunexpectedMatcher, err = geodata.IPReg.BuildIPMatcher(ns.UnexpectedIp)\n\t\t\tif err != nil {\n\t\t\t\treturn errors.New(\"failed to create unexpected ip matcher\").Base(err).AtWarning()\n\t\t\t}\n\t\t}\n\n\t\tif len(clientIP) > 0 {\n\t\t\tswitch ns.Address.Address.GetAddress().(type) {\n\t\t\tcase *net.IPOrDomain_Domain:\n\t\t\t\terrors.LogInfo(ctx, \"DNS: client \", ns.Address.Address.GetDomain(), \" uses clientIP \", clientIP.String())\n\t\t\tcase *net.IPOrDomain_Ip:\n\t\t\t\terrors.LogInfo(ctx, \"DNS: client \", net.IP(ns.Address.Address.GetIp()), \" uses clientIP \", clientIP.String())","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/app/dns/nameserver.go#L98-L134","documentation":"On a range-based turn, readPaddingTurn requires the peer's total turn length to fall within [turn.minLength, turn.maxLength] (paddingTurnAcceptsLength). The received length is outside that window, meaning the two endpoints' length bounds for this turn disagree.","triggerScenarios":"Sender's minLength/maxLength (or its send range draw) yields a length the receiver's [minLength, maxLength] does not cover; asymmetric configs where one side widened or narrowed the range; note the receiver checks its own bounds, not the sender's send range.","commonSituations":"Tuning padding bounds on the server but not clients; sending with a send range wider than the receiver's accept range (send range validation only checks it fits the sender's own bounds); version skew after config rollout.","solutions":["Set identical minLength/maxLength for each turn on both peers","Ensure any sendMinLength/sendMaxLength on the sender is within the receiver's accept window for that turn","Roll out schedule changes atomically to both endpoints"],"exampleFix":"// before: sender sends 100-2000, receiver accepts 100-1000\n// receiver turn: {minLength: 100, maxLength: 1000}\n// after\n// receiver turn: {minLength: 100, maxLength: 2000}","handlingStrategy":"validation","validationCode":"func rangesOverlap(sender, receiver paddingTurn) bool {\n    lo, hi := sender.minLength, sender.maxLength\n    if sender.sendMinLength != 0 || sender.sendMaxLength != 0 {\n        lo, hi = sender.sendMinLength, sender.sendMaxLength\n    }\n    return lo >= receiver.minLength && hi <= receiver.maxLength\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"is outside\") {\n    // bounds skew: align minLength/maxLength on both peers, then reconnect\n}","preventionTips":["Mirror the bounds of every receive turn onto the peer's send capability","Roll out bound changes to both endpoints atomically"],"tags":["padding","config","protocol-mismatch","range","xmc"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}