{"record":{"id":"fd2213c398fb822f","repo":"XTLS/Xray-core","slug":"failed-to-create-unexpected-ip-matcher","errorCode":null,"errorMessage":"failed to create unexpected ip matcher","messagePattern":"failed to create unexpected ip matcher","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/dns/nameserver.go","lineNumber":125,"sourceCode":"\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())\n\t\t\t}\n\t\t}\n\n\t\ttimeoutMs := 4000 * time.Millisecond\n\t\tif ns.TimeoutMs > 0 {\n\t\t\ttimeoutMs = time.Duration(ns.TimeoutMs) * time.Millisecond\n\t\t}\n\n\t\tcheckSystem := ns.QueryStrategy == QueryStrategy_USE_SYS","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/app/dns/nameserver.go#L107-L143","documentation":"After the header and length checks pass, readPaddingTurn drains the padding body in 16 KiB reads via io.ReadFull; this error wraps that read failing. It means the connection died or truncated mid-turn: EOF/ErrUnexpectedEOF (peer closed before sending all padding bytes), reset, deadline exceeded, or read-side cancellation.","triggerScenarios":"Peer aborts after sending only part of its padding record; read deadline shorter than the peer's injected padding delays; middlebox cutting long padded bursts; TLS layer failing underneath.","commonSituations":"Aggressive chunk delays on the sender exceeding the receiver's read timeout; mobile networks dropping mid-handshake; LBs with per-read idle limits; sender crashing between chunks.","solutions":["Raise the connection read deadline above the sender's maximum total padding delay (start delay + sum of chunk delays)","Classify via errors.Is(err, io.ErrUnexpectedEOF) etc. and reconnect - partial turns cannot be resumed","Reduce configured delay ranges if intermediaries time out the padded stream"],"exampleFix":"// before\nconn.SetReadDeadline(time.Now().Add(500 * time.Millisecond))\n// after\nconn.SetReadDeadline(time.Now().Add(30 * time.Second))","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := readPaddingTurn(r, turn, prefix); err != nil {\n    if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) || os.IsTimeout(errors.Unwrap(err)) {\n        // truncated/dead turn: discard connection, reconnect with backoff\n    }\n}","preventionTips":["Size read deadlines above the schedule's worst-case total delay","Cap sender-side delay ranges below intermediary idle timeouts","Never resume a partially read padding turn"],"tags":["padding","network","io","read","timeout","xmc"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}