apache/cassandra · error · IllegalStateException

Binlog is already configured

Error message

Binlog is already configured

What it means

FullQueryLogger.enable() throws this IllegalStateException if a BinLog instance is already attached to the singleton FullQueryLogger. Full query logging (fql) is an exclusive resource: only one binlog (writer, path, roll cycle) can be active at a time, so re-enabling without first calling stop()/disable() is rejected. It is a guarded state transition, not an I/O failure.

Solutions

  1. Check current state first with FullQueryLogger.instance.isEnabled() and skip enable() if already true.
  2. Call FullQueryLogger.instance.stop() (nodetool disablefullquerylog) before re-enabling with new parameters.
  3. If the intent was to change parameters, disable, then enable with the desired path/rollCycle/maxLogSize.
  4. If fql state is stale after a failed shutdown, ensure the binlog is closed (stop()) before retrying enable.

Example fix

// before
fullQueryLogger.enable(path, rollCycle, blocking, weight, maxLogSize, archiveCommand, retries);
// after
if (!fullQueryLogger.isEnabled())
{
    fullQueryLogger.enable(path, rollCycle, blocking, weight, maxLogSize, archiveCommand, retries);
}
else
{
    fullQueryLogger.stop();
    fullQueryLogger.enable(path, rollCycle, blocking, weight, maxLogSize, archiveCommand, retries);
}
Defensive patterns

Strategy: validation

Validate before calling

if (FullQueryLogger.instance.isEnabled())
    throw new IllegalStateException("FQL already enabled; call stop() first");

Try / catch

try { fql.enable(...); } catch (IllegalStateException e) { logger.info("FQL already enabled, ignoring: {}", e.getMessage()); }

Prevention

When it happens

Trigger: Calling FullQueryLogger.instance.enable(...) (directly or via nodetool enablefullquerylog / JMX) when fql was already enabled earlier in the node's lifetime and never disabled. Also triggered by scripting enable twice, or enable() after enableWithoutClean() without a disable in between.

Common situations: Automation/ops scripts that call enablefullquerylog on every deploy without checking current state; restoring a config-management run that re-applies an fql setting; mistakenly assuming enable() is idempotent (it reconfigures nothing — the existing binlog keeps its original parameters).

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/12b5e09013ce80b1. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/fql/FullQueryLogger.java:95

    public static final String BATCH = "batch";
    public static final String SINGLE_QUERY = "single-query";

    public static final String QUERY = "query";
    public static final String BATCH_TYPE = "batch-type";
    public static final String QUERIES = "queries";
    public static final String VALUES = "values";

    private static final int EMPTY_LIST_SIZE = Ints.checkedCast(ObjectSizes.measureDeep(new ArrayList<>(0)));
    private static final int EMPTY_BYTEBUF_SIZE;

    public static final FullQueryLogger instance = new FullQueryLogger();

    volatile BinLog binLog;

    public synchronized void enable(Path path, String rollCycle, boolean blocking, int maxQueueWeight, long maxLogSize, String archiveCommand, int maxArchiveRetries)
    {
        if (this.binLog != null)
            throw new IllegalStateException("Binlog is already configured");
        this.binLog = new BinLog.Builder().path(path)
                                          .rollCycle(rollCycle)
                                          .blocking(blocking)
                                          .maxQueueWeight(maxQueueWeight)
                                          .maxLogSize(maxLogSize)
                                          .archiveCommand(archiveCommand)
                                          .maxArchiveRetries(maxArchiveRetries)
                                          .build(true);
        QueryEvents.instance.registerListener(this);
    }

    public synchronized void enableWithoutClean(Path path, String rollCycle, boolean blocking, int maxQueueWeight, long maxLogSize, String archiveCommand, int maxArchiveRetries)
    {
        if (this.binLog != null)
            throw new IllegalStateException("Binlog is already configured");
        this.binLog = new BinLog.Builder().path(path)
                                          .rollCycle(rollCycle)
                                          .blocking(blocking)

View on GitHub (pinned to 88fd0f6a0e)