apache/cassandra · error · java.lang.IllegalArgumentException

MBeanServer already initialized

Error message

MBeanServer already initialized

What it means

The proxy stores its single MBeanServer reference in the field mbs and treats it as write-once. A second setMBeanServer call after initialization throws IllegalArgumentException("MBeanServer already initialized") at line 187. This protects against hot-swapping the server out from under live connections and cached authorization state.

Source

Thrown at src/java/org/apache/cassandra/auth/jmx/AuthorizationProxy.java:187

        {
            if ("getMBeanServer".equals(methodName))
                throw new SecurityException("Access denied");

            // Corresponds to MBeanServer.invoke
            if (methodName.equals("invoke") && args.length == 4)
                checkVulnerableMethods(args);

            // Allow setMBeanServer iff performed on behalf of the connector server itself
            if (("setMBeanServer").equals(methodName))
            {
                if (subject != null)
                    throw new SecurityException("Access denied");

                if (args[0] == null)
                    throw new IllegalArgumentException("Null MBeanServer");

                if (mbs != null)
                    throw new IllegalArgumentException("MBeanServer already initialized");

                mbs = (MBeanServer) args[0];
                return null;
            }

            if (authorize(subject, methodName, args))
            {
                Object invoke = invoke(method, args);
                listener.onInvocation(subject, method, args);
                return invoke;
            }

            throw new SecurityException("Access Denied");
        }
        catch (Exception e)
        {
            listener.onFailure(subject, method, args, e);
            throw e;

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Do not call setMBeanServer more than once per proxy; construct a fresh AuthorizationProxy for each new connector server.
  2. If re-initializing in tests, build a new proxy instance (or reset mbs via the test-visible setter) before calling setMBeanServer again.
  3. Reuse the already-initialized MBeanServer instead of trying to replace it.

Example fix

// before
AuthorizationProxy proxy = new AuthorizationProxy(...); // created earlier and already set
proxy.setMBeanServer(newServer); // IllegalStateException/IAX: already initialized
// after
AuthorizationProxy proxy = new AuthorizationProxy(); // fresh instance per connector
proxy.setMBeanServer(newServer);
Defensive patterns

Strategy: validation

Validate before calling

// guard at the call site: setMBeanServer is write-once per proxy
if (proxyAlreadyInitialized)
    throw new IllegalStateException("Create a new AuthorizationProxy instead of re-initializing the existing one");

Try / catch

try {
    proxy.setMBeanServer(server);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("already initialized")) {
        logger.info("MBeanServer already set; reusing existing instance");
    } else throw e;
}

Prevention

When it happens

Trigger: setMBeanServer called with subject == null and a non-null server, while AuthorizationProxy.mbs has already been set by an earlier setMBeanServer during connector startup.

Common situations: Creating a second JMXConnectorServer that reuses the same proxy; restarting the connector within the same JVM without recreating the proxy; test suites that bootstrap Cassandra's JMX setup multiple times in one JVM.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/a9a5d0774e69941e. Report an issue: GitHub.