{"record":{"id":"49f0364378e17cda","repo":"aeron-io/aeron","slug":"initial-window-greater-than-so-rcvbuf-for-channel-rcv-wnd","errorCode":null,"errorMessage":"Initial window greater than SO_RCVBUF for channel: rcv-wnd=<receiverWindowLength> so-rcvbuf=<channelSocketRcvbufLength> existingChannel=<existingChannel> channel=<channel>","messagePattern":"Initial window greater than SO_RCVBUF for channel: rcv-wnd=<receiverWindowLength> so-rcvbuf=<channelSocketRcvbufLength> existingChannel=<existingChannel> channel=<channel>","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"aeron-driver/src/main/java/io/aeron/driver/SubscriptionParams.java","lineNumber":177,"sourceCode":"            channelUri, UNTETHERED_RESTING_TIMEOUT_PARAM_NAME, ctx.untetheredRestingTimeoutNs());\n    }\n\n    private static long getTimeoutNs(final ChannelUri channelUri, final String paramName, final long defaultValue)\n    {\n        final String timeoutString = channelUri.get(paramName);\n        return null != timeoutString ? SystemUtil.parseDuration(paramName, timeoutString) : defaultValue;\n    }\n\n    static void validateInitialWindowForRcvBuf(\n        final SubscriptionParams params,\n        final String channel,\n        final int channelSocketRcvbufLength,\n        final MediaDriver.Context ctx,\n        final String existingChannel)\n    {\n        if (0 != channelSocketRcvbufLength && params.receiverWindowLength > channelSocketRcvbufLength)\n        {\n            throw new IllegalStateException(\n                \"Initial window greater than SO_RCVBUF for channel: rcv-wnd=\" + params.receiverWindowLength +\n                \" so-rcvbuf=\" + channelSocketRcvbufLength +\n                (null == existingChannel ? \"\" : (\" existingChannel=\" + existingChannel)) + \" channel=\" + channel);\n        }\n        else if (0 == channelSocketRcvbufLength && params.receiverWindowLength > ctx.osDefaultSocketRcvbufLength())\n        {\n            throw new IllegalStateException(\n                \"Initial window greater than SO_RCVBUF for channel: rcv-wnd=\" + params.receiverWindowLength +\n                \" so-rcvbuf=\" + ctx.osDefaultSocketRcvbufLength() + \" (OS default)\" +\n                (null == existingChannel ? \"\" : (\" existingChannel=\" + existingChannel)) + \" channel=\" + channel);\n        }\n    }\n\n    public String toString()\n    {\n        return \"SubscriptionParams\" +\n            \"\\n{\" +\n            \"\\n    initialTermId=\" + initialTermId +","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-driver/src/main/java/io/aeron/driver/SubscriptionParams.java#L159-L195","documentation":"Aeron validates that a subscription's initial receiver window (rcv-wnd) does not exceed the channel's SO_RCVBUF when an explicit so-rcvbuf is set. An initial window larger than the socket receive buffer can lose data, so the driver throws IllegalStateException, including the existing channel when merging with an existing subscription.","triggerScenarios":"Adding a subscription whose receiver-window-length param exceeds the URI's so-rcvbuf value (which must be > 0), e.g. ...|rcv-wnd=8388608|so-rcvbuf=1048576.","commonSituations":"Tuning for throughput by raising rcv-wnd while so-rcvbuf remains small; OS limits capping the actual SO_RCVBUF; merging subscriptions where an existing channel has a smaller buffer.","solutions":["Raise so-rcvbuf in the channel URI to at least the receiver-window-length value.","Lower receiver-window-length so it does not exceed so-rcvbuf.","Increase the OS receive buffer limits (net.core.rmem_max on Linux) if so-rcvbuf cannot be applied.","Align parameters with any existing subscription on the same channel to avoid merge-time conflicts."],"exampleFix":"// before\n\"aeron:udp?endpoint=localhost:40456|rcv-wnd=8388608|so-rcvbuf=1048576\"\n// after\n\"aeron:udp?endpoint=localhost:40456|rcv-wnd=8388608|so-rcvbuf=8388608\"","handlingStrategy":"validation","validationCode":"if (soRcvbuf > 0 && rcvWnd > soRcvbuf) {\n    throw new IllegalArgumentException(\"rcv-wnd (\" + rcvWnd + \") must be <= so-rcvbuf (\" + soRcvbuf + \")\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    subscription = aeron.addSubscription(channel, streamId, availableImageHandler, null);\n} catch (AeronException e) {\n    if (e.getMessage().startsWith(\"Initial window greater than SO_RCVBUF\")) { /* raise so-rcvbuf or lower rcv-wnd */ }\n    throw e;\n}","preventionTips":["Keep so-rcvbuf >= rcv-wnd in channel configs.","Check OS net.core.rmem_max when tuning large windows.","Use consistent params across subscriptions sharing a channel."],"tags":["aeron","network","socket-buffer","tuning"],"backgroundTag":"conflicting-config-options","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}