apache/kafka · error · IllegalStateException

MockProducer hasn't been initialized for transactions.

Error message

MockProducer hasn't been initialized for transactions.

What it means

Thrown by MockProducer.verifyTransactionsInitialized() as an IllegalStateException when a transactional method is invoked before initTransactions() has been called. MockProducer only sets `transactionInitialized = true` inside initTransactions() (line 165); beginTransaction(), commitTransaction(), abortTransaction(), sendOffsetsToTransaction(), prepareTransaction(), completeTransaction(), and fenceProducer() all require that precondition. It mirrors the real producer's contract that the transactional.id must be resolved and the producer epoch established before any transactional work.

Source

Thrown at clients/src/main/java/org/apache/kafka/clients/producer/MockProducer.java:306

            abortTransaction();
        }
    }

    private synchronized void verifyNotClosed() {
        if (this.closed) {
            throw new IllegalStateException("MockProducer is already closed.");
        }
    }

    private synchronized void verifyNotFenced() {
        if (this.producerFenced) {
            throw new ProducerFencedException("MockProducer is fenced.");
        }
    }

    private void verifyTransactionsInitialized() {
        if (!this.transactionInitialized) {
            throw new IllegalStateException("MockProducer hasn't been initialized for transactions.");
        }
    }

    private void verifyTransactionInFlight() {
        if (!this.transactionInFlight) {
            throw new IllegalStateException("There is no open transaction.");
        }
    }

    /**
     * Adds the record to the list of sent records. The {@link RecordMetadata} returned will be immediately satisfied.
     *
     * @see #history()
     */
    @Override
    public synchronized Future<RecordMetadata> send(ProducerRecord<K, V> record) {
        return send(record, null);
    }

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Call producer.initTransactions(false) (or initTransactions(true) when testing prepared-state flows) before beginTransaction/commitTransaction/etc.
  2. If initTransactionException was set, verify the exception was expected and that production code recovers by retrying init or aborting — do not proceed to beginTransaction after a failed init.
  3. Centralize the initTransactions() call in the test's @BeforeEach so every transactional test starts from an initialized producer.
  4. Check the production code under test: if it relies on lazy initialization, ensure that path is actually taken before the first transactional call.

Example fix

// before
MockProducer<String,String> p = new MockProducer<>();
p.beginTransaction(); // IllegalStateException

// after
MockProducer<String,String> p = new MockProducer<>();
p.initTransactions(false);
p.beginTransaction();
Defensive patterns

Strategy: validation

Validate before calling

// Call initTransactions() exactly once before any txn API.
// Track initialization locally so you never call commit/abort/prepare first.
boolean initialized = false;
void ensureTxnInit(MockProducer<?,?> p) {
    if (!initialized) {
        p.initTransactions();
        initialized = true;
    }
}
// call ensureTxnInit(producer) before beginTransaction()/completeTransaction()

Prevention

When it happens

Trigger: Calling beginTransaction(), commitTransaction(), abortTransaction(), sendOffsetsToTransaction(...), prepareTransaction(), completeTransaction(...), or fenceProducer() without first calling initTransactions(boolean) on the mock. The check happens at line 304-308 before the method does any real work.

Common situations: A test that drives transactional send/commit logic but skips the initTransactions step because the production wrapper hides it; upgrading a test from non-transactional to transactional usage without adding the init call; an initTransactions() call that threw initTransactionException (so transactionInitialized stayed false) followed by beginTransaction().

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/ec23a2909226310f.json. Report an issue: GitHub.