t8y2/dbx · error · IllegalArgumentException

${name} must be a positive integer

Error message

${name} must be a positive integer

What it means

positiveTimeoutMs is the shared guard used by KafkaAgent for timeout settings (request.timeout.ms and similar). It throws this IllegalArgumentException when a timeout was parsed successfully but is <= 0, because Kafka requires strictly positive timeouts. Message text interpolates the offending config key via `name`.

Source

Thrown at agents/drivers/kafka/src/main/java/com/dbx/agent/kafka/KafkaAgent.java:1735

        if (connectionTimeout != null) {
            return positiveTimeoutMs("request_timeout_ms", connectionTimeout);
        }
        String configuredTimeout = props.getProperty(
            ConsumerConfig.REQUEST_TIMEOUT_MS_CONFIG,
            String.valueOf(DEFAULT_REQUEST_TIMEOUT_MS)
        );
        try {
            return positiveTimeoutMs(ConsumerConfig.REQUEST_TIMEOUT_MS_CONFIG, Integer.parseInt(configuredTimeout));
        } catch (NumberFormatException error) {
            throw new IllegalArgumentException(
                ConsumerConfig.REQUEST_TIMEOUT_MS_CONFIG + " must be a positive integer", error
            );
        }
    }

    private static int positiveTimeoutMs(String name, int timeoutMs) {
        if (timeoutMs <= 0) {
            throw new IllegalArgumentException(name + " must be a positive integer");
        }
        return timeoutMs;
    }

    static Properties peekConsumerProperties(JsonObject conn, int count) {
        Properties props = new Properties();
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers(conn));
        applyConnectionProperties(conn, props);
        props.put(ConsumerConfig.GROUP_ID_CONFIG, "dbx-peek-" + UUID.randomUUID());
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG,
            "org.apache.kafka.common.serialization.StringDeserializer");
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,
            "org.apache.kafka.common.serialization.ByteArrayDeserializer");
        props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false");
        props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "none");
        props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, count);
        return props;
    }

View on GitHub (pinned to c0390bff16)

Solutions

  1. Set the timeout property to a positive integer (> 0) in milliseconds.
  2. Omit the property entirely to use the driver default instead of specifying 0.
  3. Sanitize computed timeout values with Math.max(1, value) before applying config.

Example fix

// before
config.put("request.timeout.ms", 0); // meant 'no timeout'

// after
config.put("request.timeout.ms", 30000); // or omit to use default
Defensive patterns

Strategy: validation

Validate before calling

if (timeoutMs <= 0) {
    throw new IllegalArgumentException(name + " must be a positive integer");
}

Type guard

boolean isPositiveTimeout(int timeoutMs) { return timeoutMs > 0; }

Try / catch

try {
    consumer = agent.connect(conn);
} catch (IllegalArgumentException e) {
    if (e.getMessage().endsWith("must be a positive integer")) {
        log.warn("Bad timeout config; using driver default");
        conn.remove("request.timeout.ms");
        consumer = agent.connect(conn);
    } else throw e;
}

Prevention

When it happens

Trigger: Passing request.timeout.ms (or another timeout property routed through positiveTimeoutMs) as 0 or a negative integer in the connection config.

Common situations: Setting the timeout to 0 believing it means 'no timeout' or 'infinite'; templating a value with a default of -1 as 'unset'; computing a timeout from a clock diff that yielded 0.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/907a89e1f1fb09d9. Report an issue: GitHub.