{"record":{"id":"22dc7c4fdc926ead","repo":"XTLS/Xray-core","slug":"dispatcher-invalid-destination","errorCode":null,"errorMessage":"Dispatcher: Invalid destination.","messagePattern":"Dispatcher: Invalid destination\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/dispatcher/default.go","lineNumber":326,"sourceCode":"\t\t\t\tif fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && fkr0.IsIPInIPPool(ob.Target.Address) {\n\t\t\t\t\tisFakeIP = true\n\t\t\t\t}\n\t\t\t\tif sniffingRequest.RouteOnly && protocol != \"fakedns\" && protocol != \"fakedns+others\" && !isFakeIP {\n\t\t\t\t\tob.RouteTarget = destination\n\t\t\t\t} else {\n\t\t\t\t\tob.Target = destination\n\t\t\t\t}\n\t\t\t}\n\t\t\td.routedDispatch(ctx, outbound, destination)\n\t\t}()\n\t}\n\treturn inbound, nil\n}\n\n// DispatchLink implements routing.Dispatcher.\nfunc (d *DefaultDispatcher) DispatchLink(ctx context.Context, destination net.Destination, outbound *transport.Link) error {\n\tif !destination.IsValid() {\n\t\treturn errors.New(\"Dispatcher: Invalid destination.\")\n\t}\n\toutbounds := session.OutboundsFromContext(ctx)\n\tif len(outbounds) == 0 {\n\t\toutbounds = []*session.Outbound{{}}\n\t\tctx = session.ContextWithOutbounds(ctx, outbounds)\n\t}\n\tob := outbounds[len(outbounds)-1]\n\tob.OriginalTarget = destination\n\tob.Target = destination\n\tcontent := session.ContentFromContext(ctx)\n\tif content == nil {\n\t\tcontent = new(session.Content)\n\t\tctx = session.ContextWithContent(ctx, content)\n\t}\n\toutbound = WrapLink(ctx, d.policy, d.stats, outbound)\n\tsniffingRequest := content.SniffingRequest\n\tif !sniffingRequest.Enabled {\n\t\td.routedDispatch(ctx, outbound, destination)","sourceCodeStart":308,"sourceCodeEnd":344,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/app/dispatcher/default.go#L308-L344","documentation":"validatePaddingSchedule rejects a send range that does not fit inside the turn's overall length bounds or is internally unordered. The checks are sendMinLength >= minLength, sendMaxLength >= sendMinLength, and sendMaxLength <= maxLength, where minLength/maxLength come from paddingTurnBounds. The send range picks what this side actually transmits, so it must be a sub-range of the negotiated turn bounds.","triggerScenarios":"A turn with sendMinLength/sendMaxLength set where sendMinLength < turn.minLength, sendMaxLength > turn.maxLength, or sendMaxLength < sendMinLength. Fails during validatePaddingSchedule before any bytes are written.","commonSituations":"Setting sendMaxLength larger than maxLength expecting the send range to widen the turn (it cannot); swapping min/max fields by hand; editing only one end of the range during tuning; stale maxLength after lowering the turn bound.","solutions":["Clamp the send range to [turn.minLength, turn.maxLength]: sendMinLength >= minLength and sendMaxLength <= maxLength","Ensure sendMinLength <= sendMaxLength","If a wider send range is actually needed, raise minLength/maxLength of the turn itself first"],"exampleFix":"// before\npaddingTurn{\n  minLength: 200, maxLength: 1000,\n  sendMinLength: 100, sendMaxLength: 2000,\n}\n// after\npaddingTurn{\n  minLength: 200, maxLength: 1000,\n  sendMinLength: 200, sendMaxLength: 1000,\n}","handlingStrategy":"validation","validationCode":"func sendRangeFits(t paddingTurn) bool {\n    if t.sendMinLength == 0 && t.sendMaxLength == 0 {\n        return true\n    }\n    return t.sendMinLength >= t.minLength &&\n        t.sendMaxLength >= t.sendMinLength &&\n        t.sendMaxLength <= t.maxLength\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive send range from the bounds in code (sendMin = minLength + jitter) instead of typing two independent ranges","Validate before connecting, not on failure","Watch for maxLength edits that forget to re-clamp the send range"],"tags":["padding","config","validation","range","xmc"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}