apache/kafka · info · TimeoutException

TimeoutExceptions are successfully injected for test.

Error message

TimeoutExceptions are successfully injected for test.

What it means

Thrown by MockProducer.clientInstanceId(Duration) as a TimeoutException (note: success-path signalling) when the test has armed timeout injection via injectTimeoutException(int). Each call to clientInstanceId() decrements the counter (or stays infinite for -1) and throws this exception until the counter reaches zero. It lets tests deterministically simulate broker telemetry timeouts without a real network.

Source

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

     */
    public void setClientInstanceId(final Uuid instanceId) {
        clientInstanceId = instanceId;
    }

    @Override
    public Uuid clientInstanceId(Duration timeout) {
        if (telemetryDisabled) {
            throw new IllegalStateException();
        }
        if (clientInstanceId == null) {
            throw new UnsupportedOperationException("clientInstanceId not set");
        }
        if (injectTimeoutExceptionCounter != 0) {
            // -1 is used as "infinite"
            if (injectTimeoutExceptionCounter > 0) {
                --injectTimeoutExceptionCounter;
            }
            throw new TimeoutException("TimeoutExceptions are successfully injected for test.");
        }

        return clientInstanceId;
    }

    public Map<MetricName, Metric> metrics() {
        return mockMetrics;
    }

    /**
     * Set a mock metric for testing purpose
     */
    public void setMockMetrics(MetricName name, Metric metric) {
        mockMetrics.put(name, metric);
    }

    @Override
    public void close() {

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Call injectTimeoutException(0) (or create a fresh MockProducer) once you want clientInstanceId() to return normally again.
  2. In the test, drive the expected number of timeout retries then assert the call succeeds on the next attempt.
  3. Do not use -1 (infinite) unless the test specifically checks unbounded retries; prefer an exact count.
  4. If this exception reaches production-looking code in a test, confirm the production retry/backoff logic calls close() and exits after exhausting retries instead of looping forever.

Example fix

// before
producer.injectTimeoutException(3);
Uuid id = producer.clientInstanceId(Duration.ofSeconds(1)); // TimeoutException x3

// after
producer.injectTimeoutException(3);
for (int i = 0; i < 3; i++) {
    try { producer.clientInstanceId(Duration.ofSeconds(1)); }
    catch (TimeoutException expected) { /* retry */ }
}
Uuid id = producer.clientInstanceId(Duration.ofSeconds(1)); // now returns
Defensive patterns

Strategy: retry

Validate before calling

// Before calling clientInstanceId(), check the injected-timeout counter
// state if your test exposes it; otherwise just retry with backoff.
// Typical defensive wrapper:
Uuid getClientInstanceIdWithRetry(MockProducer<?,?> p, Duration perTry, int maxAttempts) {
    RuntimeException last = null;
    for (int i = 0; i < maxAttempts; i++) {
        try {
            return p.clientInstanceId(perTry);
        } catch (org.apache.kafka.common.errors.TimeoutException te) {
            last = te;
            // backoff before next attempt
        }
    }
    throw last;
}

Prevention

When it happens

Trigger: Calling producer.clientInstanceId(timeout) after producer.injectTimeoutException(n) with n>0 or n=-1. The throw at line 448 occurs only when telemetry is not disabled and clientInstanceId is already set (otherwise the earlier guards fire). Counter is decremented at line 446.

Common situations: A test asserting that the application retries clientInstanceId() after a timeout; setting injectTimeoutException(-1) (infinite) and forgetting to reset it, so subsequent tests on the same instance never succeed; a test expecting the value but the injection was left armed from a previous case.

Related errors


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