{"record":{"id":"7ffa085aa2543929","repo":"aeron-io/aeron","slug":"either-endpoint-or-control-must-be-specified-for-udp","errorCode":null,"errorMessage":"either 'endpoint' or 'control' must be specified for UDP.","messagePattern":"either 'endpoint' or 'control' must be specified for UDP\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"aeron-client/src/main/java/io/aeron/ChannelUriStringBuilder.java","lineNumber":221,"sourceCode":"        return this;\n    }\n\n    /**\n     * Validates that the collection of set parameters are valid together.\n     *\n     * @return this for a fluent API.\n     * @throws IllegalArgumentException if the combination of params is invalid.\n     */\n    public ChannelUriStringBuilder validate()\n    {\n        if (null == media)\n        {\n            throw new IllegalArgumentException(\"media type is mandatory\");\n        }\n\n        if (CommonContext.UDP_MEDIA.equals(media) && (null == endpoint && null == controlEndpoint))\n        {\n            throw new IllegalArgumentException(\"either 'endpoint' or 'control' must be specified for UDP.\");\n        }\n\n        final boolean anyNonNull = null != initialTermId || null != termId || null != termOffset;\n        final boolean anyNull = null == initialTermId || null == termId || null == termOffset;\n        if (anyNonNull)\n        {\n            if (anyNull)\n            {\n                throw new IllegalArgumentException(\n                    \"either all or none of the parameters ['initialTermId', 'termId', 'termOffset'] must be provided\");\n            }\n\n            if (termId - initialTermId < 0)\n            {\n                throw new IllegalArgumentException(\n                    \"difference greater than 2^31 - 1: termId=\" + termId + \" - initialTermId=\" + initialTermId);\n            }\n","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-client/src/main/java/io/aeron/ChannelUriStringBuilder.java#L203-L239","documentation":"For UDP channels, validate() requires a routing destination: either a unicast/multicast endpoint or a control (multicast) endpoint must be set. A UDP media with both endpoint and controlEndpoint null has nowhere to send, so IllegalArgumentException is thrown.","triggerScenarios":"Builder with media(\"udp\") but neither .endpoint(...) nor .control(...) called, then validate()/build(). IPC channels are exempt from this check.","commonSituations":"Reusing a builder configured for IPC with UDP media; config file that specifies transport=udp but omits endpoint/control keys; code paths that assume a default endpoint exists.","solutions":["Add .endpoint(\"host:port\") (or .control(multicastAddress:port)) to the builder for UDP channels","Verify the config actually contains the endpoint or control value and that the key name matches","If the channel is genuinely local-only, use media \"ipc\" instead of udp"],"exampleFix":"// before\nnew ChannelUriStringBuilder().media(CommonContext.UDP_MEDIA).validate();\n// after\nnew ChannelUriStringBuilder()\n    .media(CommonContext.UDP_MEDIA)\n    .endpoint(\"localhost:40456\")\n    .validate();","handlingStrategy":"validation","validationCode":"static void requireUdpDestination(String media, String endpoint, String control) {\n    if (\"udp\".equals(media) && endpoint == null && control == null) {\n        throw new IllegalArgumentException(\"udp channel requires 'endpoint' or 'control'\");\n    }\n}","typeGuard":"static boolean hasUdpDestination(ChannelUriStringBuilder b) {\n    try { b.validate(); return true; } catch (IllegalArgumentException e) { return false; }\n}","tryCatchPattern":"try {\n    String uri = builder.validate().build();\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"either 'endpoint' or 'control'\")) {\n        throw new IllegalArgumentException(\"UDP channel config must set endpoint or control\", e);\n    }\n    throw e;\n}","preventionTips":["For every udp channel, set endpoint (unicast/multicast) or control (MDC)","If the channel is local-only, switch to media \"ipc\" instead of udp","Keep endpoint/control config keys in one schema and validate before building URIs"],"tags":["uri-builder","udp","validation","aeron"],"backgroundTag":"missing-required-config-field","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}