# org.apache.kafka.common.errors.ProducerFencedException: Producer epoch fenced due to partition reassignment

- **ID:** `kafka/transactional-producer-epoch-fenced-during-partition-reassignment`
- **Domain:** kafka
- **Category:** protocol_error
- **Verification:** ai_generated
- **Fix Rate:** 81%

## Root Cause

A transactional producer's epoch was invalidated because a partition it was writing to was reassigned to a different broker, causing the transaction coordinator to fence the producer.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| Kafka 3.3.0 | active | — | — |
| Kafka 3.5.0 | active | — | — |
| Kafka 3.7.0 | active | — | — |

## Workarounds

1. **Initialize a new transactional producer with a new transactional.id after catching the exception. Example in Java: try { producer.initTransactions(); } catch (ProducerFencedException e) { producer.close(); producer = createNewProducerWithNewTransactionalId(); producer.initTransactions(); }** (90% success)
   ```
   Initialize a new transactional producer with a new transactional.id after catching the exception. Example in Java: try { producer.initTransactions(); } catch (ProducerFencedException e) { producer.close(); producer = createNewProducerWithNewTransactionalId(); producer.initTransactions(); }
   ```
2. **Ensure partition reassignment is completed before starting transactional writes. Use 'bin/kafka-reassign-partitions.sh --bootstrap-server localhost:9092 --verify --reassignment-json-file reassign.json' to confirm completion.** (85% success)
   ```
   Ensure partition reassignment is completed before starting transactional writes. Use 'bin/kafka-reassign-partitions.sh --bootstrap-server localhost:9092 --verify --reassignment-json-file reassign.json' to confirm completion.
   ```

## Dead Ends

- **Setting transaction.timeout.ms to 300000 (5 minutes)** — Increasing transaction.timeout.ms does not prevent epoch fencing; it only delays transaction expiration. (90% fail)
- **Restarting the producer application without changing transactional.id** — Restarting the producer without resetting the transactional.id will still use the fenced epoch. (95% fail)
