Thomas Steinmaurer created CASSANDRA-21491:
----------------------------------------------

             Summary: NPE in ClientMetrics.unpauseConnectionClient
                 Key: CASSANDRA-21491
                 URL: https://issues.apache.org/jira/browse/CASSANDRA-21491
             Project: Apache Cassandra
          Issue Type: Bug
            Reporter: Thomas Steinmaurer
         Attachments: image-2026-07-08-10-20-27-313.png

With Cassandra 4.1.11, from time to time we see the following NPE in production:

{code:java}
ERROR [Messaging-EventLoop-3-9] 2026-07-07 14:31:19,408 
InboundMessageHandler.java:298 - 
/10.244.123.131:7000->/10.244.18.26:7000-LARGE_MESSAGES-24ff2250 unexpected 
exception caught while processing inbound messages; terminating connection
java.lang.NullPointerException: null
        at 
org.apache.cassandra.metrics.ClientMetrics.unpauseConnection(ClientMetrics.java:91)
        at 
org.apache.cassandra.net.AbstractMessageHandler.onReserveCapacityRegained(AbstractMessageHandler.java:314)
        at 
org.apache.cassandra.net.AbstractMessageHandler.onGlobalReserveCapacityRegained(AbstractMessageHandler.java:289)
        at 
org.apache.cassandra.net.AbstractMessageHandler.access$1600(AbstractMessageHandler.java:134)
        at 
org.apache.cassandra.net.AbstractMessageHandler$WaitQueue$Ticket.reactivateHandler(AbstractMessageHandler.java:792)
        at 
org.apache.cassandra.net.AbstractMessageHandler$WaitQueue$Ticket.access$1200(AbstractMessageHandler.java:759)
        at 
org.apache.cassandra.net.AbstractMessageHandler$WaitQueue$ReactivateHandlers.run(AbstractMessageHandler.java:740)
        at 
io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
        at 
io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
        at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:384)
        at 
io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
        at 
io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
        at 
io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Unknown Source)
{code}

Throwing Claude (Sonnet 4.6) on it, I get the following:

---
Root Cause

ClientMetrics.pausedConnections is null when unpauseConnection() is called for 
inter-node connections.

The crash chain:

1. pausedConnections is only initialized in ClientMetrics.init() 
(ClientMetrics.java:145), which is called from NativeTransportService.java:120 
— i.e., only when the CQL native transport starts up.
2. Inter-node messaging (port 7000) starts earlier than the native transport 
during Cassandra startup. InboundMessageHandler extends AbstractMessageHandler 
and handles these connections.
3. AbstractMessageHandler.onReserveCapacityRegained() (line 314) 
unconditionally calls ClientMetrics.instance.unpauseConnection() — for both CQL 
client connections (correct) and inter-node LARGE_MESSAGES connections (wrong).
4. If a LARGE_MESSAGE inter-node connection gets throttled due to reserve 
capacity pressure and then the capacity is regained, this code path fires 
before ClientMetrics.init() has run → pausedConnections is still null → NPE.

---
Fix

The minimal, targeted fix is to initialize pausedConnections at field 
declaration rather than lazily inside init():

Claude proposes the following code change:

 !image-2026-07-08-10-20-27-313.png! 






--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to