apache/kafka · error · IllegalArgumentException

Topic cannot be null.

Error message

Topic cannot be null.

What it means

Thrown by the primary ProducerRecord constructor when the topic argument is null. Kafka requires every record to address a concrete topic name, so a null topic is rejected up front at construction rather than failing later inside the producer's accumulator. This is an IllegalArgumentException, so it surfaces synchronously at the call site that built the record.

Source

Thrown at clients/src/main/java/org/apache/kafka/clients/producer/ProducerRecord.java:73

    private final Headers headers;
    private final K key;
    private final V value;
    private final Long timestamp;

    /**
     * Creates a record with a specified timestamp to be sent to a specified topic and partition
     * 
     * @param topic The topic the record will be appended to
     * @param partition The partition to which the record should be sent
     * @param timestamp The timestamp of the record, in milliseconds since epoch. If null, the producer will assign
     *                  the timestamp using System.currentTimeMillis().
     * @param key The key that will be included in the record
     * @param value The record contents
     * @param headers the headers that will be included in the record
     */
    public ProducerRecord(String topic, Integer partition, Long timestamp, K key, V value, Iterable<Header> headers) {
        if (topic == null)
            throw new IllegalArgumentException("Topic cannot be null.");
        if (timestamp != null && timestamp < 0)
            throw new IllegalArgumentException(
                    String.format("Invalid timestamp: %d. Timestamp should always be non-negative or null.", timestamp));
        if (partition != null && partition < 0)
            throw new IllegalArgumentException(
                    String.format("Invalid partition: %d. Partition number should always be non-negative or null.", partition));
        this.topic = topic;
        this.partition = partition;
        this.key = key;
        this.value = value;
        this.timestamp = timestamp;
        this.headers = new RecordHeaders(headers);
    }

    /**
     * Creates a record with a specified timestamp to be sent to a specified topic and partition
     *
     * @param topic The topic the record will be appended to

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Guard the topic before construction: if (topic == null) throw or default it, then build the ProducerRecord with a non-null name.
  2. Validate that the config property, env var, or DTO field sourcing the topic is set at startup and fail-fast with a clear message instead of letting a null propagate to the constructor.
  3. Search the codebase for any ProducerRecord construction that takes a computed topic expression and ensure the expression is annotated/checked for null (e.g. Objects.requireNonNull(topic, "topic")).

Example fix

// before
String topic = config.getProperty("kafka.topic");
ProducerRecord<String,String> rec = new ProducerRecord<>(topic, value);

// after
String topic = config.getProperty("kafka.topic");
if (topic == null || topic.isEmpty())
    throw new IllegalStateException("Missing required 'kafka.topic' config");
ProducerRecord<String,String> rec = new ProducerRecord<>(topic, value);
Defensive patterns

Strategy: validation

Validate before calling

// Validate topic before constructing the record.
String topic = /* resolved topic name */;
if (topic == null) {
    throw new NullPointerException("topic must be resolved to a non-null name before sending");
}
ProducerRecord<K, V> record = new ProducerRecord<>(topic, partition, timestamp, key, value);

Type guard

// Narrows a possibly-null topic to a non-null String.
static String requireTopic(String topic) {
    if (topic == null) throw new IllegalArgumentException("topic is null");
    if (topic.isEmpty()) throw new IllegalArgumentException("topic is empty");
    return topic; // proven non-null, non-empty downstream
}

Try / catch

// Constructor throws IllegalArgumentException synchronously on a null topic,
// so prefer validation. Catch only as a safety net around record building.
try {
    ProducerRecord<K, V> r = new ProducerRecord<>(topic, partition, timestamp, key, value);
    producer.send(r);
} catch (IllegalArgumentException e) {
    // log + route to a dead-letter / skip path; do not retry the same null topic
}

Prevention

When it happens

Trigger: Constructing a ProducerRecord via any of its constructors (e.g. new ProducerRecord<>(null, value) or new ProducerRecord<>(null, partition, timestamp, key, value, headers)) with the topic argument passed as null. Also triggered when the topic string is loaded from a config, map, or deserializer that resolves to null and is forwarded into the constructor without a null check.

Common situations: Topic name read from an application config file or env var that is missing or mistyped and resolves to null; code that builds records from dynamic POJOs/DTOs where the topic field is unset; refactor that renamed a topic constant and left a stale null-producing expression; unit tests that construct records with placeholder null topics.

Related errors


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