{"record":{"id":"92d7cbf785284825","repo":"apache/cassandra","slug":"must-provide-eventloop","errorCode":null,"errorMessage":"must provide eventLoop","messagePattern":"must provide eventLoop","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/net/SocketFactory.java","lineNumber":203,"sourceCode":"    final ExecutorService synchronousWorkExecutor = executorFactory().pooled(\"Messaging-SynchronousWork\", Integer.MAX_VALUE);\n\n    SocketFactory()\n    {\n        this(Provider.optimalProvider());\n    }\n\n    SocketFactory(Provider provider)\n    {\n        this.provider = provider;\n        this.acceptGroup = provider.makeEventLoopGroup(1, \"Messaging-AcceptLoop\");\n        this.defaultGroup = provider.makeEventLoopGroup(EVENT_THREADS, NamedThreadFactory.globalPrefix() + \"Messaging-EventLoop\");\n        this.outboundStreamingGroup = provider.makeEventLoopGroup(EVENT_THREADS, \"Streaming-EventLoop\");\n    }\n\n    Bootstrap newClientBootstrap(EventLoop eventLoop, int tcpUserTimeoutInMS)\n    {\n        if (eventLoop == null)\n            throw new IllegalArgumentException(\"must provide eventLoop\");\n\n        Bootstrap bootstrap = new Bootstrap().group(eventLoop).channelFactory(provider.clientChannelFactory());\n\n        if (provider == Provider.EPOLL)\n            bootstrap.option(EpollChannelOption.TCP_USER_TIMEOUT, tcpUserTimeoutInMS);\n\n        return bootstrap;\n    }\n\n    ServerBootstrap newServerBootstrap()\n    {\n        return new ServerBootstrap().group(acceptGroup, defaultGroup).channelFactory(provider.serverChannelFactory());\n    }\n\n    /**\n     * Creates a new {@link SslHandler} from provided SslContext.\n     * @param peer enables endpoint verification for remote address when not null\n     */","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/net/SocketFactory.java#L185-L221","documentation":"Fired in SocketFactory.newClientBootstrap as a guard: a null eventLoopGroup is passed where a Netty event loop group is mandatory for building the outbound messaging client bootstrap. It is an internal precondition violation (IllegalStateException/IllegalArgumentException 'must provide eventLoop'), not a user-facing config error.","triggerScenarios":"Calling newClientBootstrap(null, timeout), typically because an outbound connection/channel factory was constructed without first obtaining an event loop from the provider's event loop group.","commonSituations":"Custom/patched transport wiring, test code building a bootstrap manually, or initialization ordering bugs where connection setup runs before the messaging event loop group is created.","solutions":["Pass the EventLoop obtained from the SocketFactory's outbound group (e.g. group.next()) to newClientBootstrap","Ensure connection setup only runs after event loop group initialization completes","In tests, provide a real event loop rather than null"],"exampleFix":"// before\nBootstrap b = factory.newClientBootstrap(null, tcpUserTimeout);\n// after\nEventLoop loop = factory.outboundEventLoopGroup().next();\nBootstrap b = factory.newClientBootstrap(loop, tcpUserTimeout);","handlingStrategy":"validation","validationCode":"if (eventLoop == null || eventLoop.isShutdown()) throw new IllegalStateException(\"event loop not ready\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always source the EventLoop from the factory's outbound event loop group","Initialize the event loop group before any connection setup","In tests, inject a real event loop, not null"],"tags":["network","netty","null-argument","bootstrap"],"backgroundTag":"null-argument","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}