apache/pulsar · error · IllegalArgumentException
Function timeout must be a positive number
Error message
Function timeout must be a positive number
What it means
timeoutMs defines how long a message may take to process before being redelivered, which only makes sense with ATLEAST_ONCE guarantees and must be a positive duration. doCommonChecks throws this IllegalArgumentException when timeoutMs is set to zero or a negative value.
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java:860
WindowConfig windowConfig = functionConfig.getWindowConfig();
if (windowConfig != null) {
// set auto ack to false since windowing framework is responsible
// for acking and not the function framework
@SuppressWarnings("deprecation")
Boolean windowAutoAck = functionConfig.getAutoAck();
if (windowAutoAck != null && windowAutoAck) {
throw new IllegalArgumentException("Cannot enable auto ack when using windowing functionality");
}
WindowConfigUtils.validate(windowConfig);
}
if (functionConfig.getResources() != null) {
ResourceConfigUtils.validate(functionConfig.getResources());
}
if (functionConfig.getTimeoutMs() != null && functionConfig.getTimeoutMs() <= 0) {
throw new IllegalArgumentException("Function timeout must be a positive number");
}
if (functionConfig.getTimeoutMs() != null
&& functionConfig.getProcessingGuarantees() != null
&& functionConfig.getProcessingGuarantees() != FunctionConfig.ProcessingGuarantees.ATLEAST_ONCE) {
throw new IllegalArgumentException("Message timeout can only be specified with processing guarantee is "
+ FunctionConfig.ProcessingGuarantees.ATLEAST_ONCE.name());
}
if (functionConfig.getMaxMessageRetries() != null && functionConfig.getMaxMessageRetries() >= 0
&& functionConfig.getProcessingGuarantees() == FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE) {
throw new IllegalArgumentException("MaxMessageRetries and Effectively once don't gel well");
}
if ((functionConfig.getMaxMessageRetries() == null || functionConfig.getMaxMessageRetries() < 0)
&& !org.apache.commons.lang3.StringUtils.isEmpty(functionConfig.getDeadLetterTopic())) {
throw new IllegalArgumentException("Dead Letter Topic specified, however max retries is set to infinity");
}
if (functionConfig.getRetainKeyOrdering() != nullView on GitHub (pinned to 820761864e)
Solutions
- Set timeoutMs to a positive millisecond value, e.g. 30000 for 30s
- To disable timeout, leave the field null/unset rather than 0
- Guard computed values: only setTimeoutMs when value > 0
Example fix
// before
config.setTimeoutMs(timeoutMs); // may be 0
// after
if (timeoutMs != null && timeoutMs > 0) {
config.setTimeoutMs(timeoutMs);
} Defensive patterns
Strategy: validation
Validate before calling
Long t = config.getTimeoutMs();
if (t != null && t <= 0) {
throw new IllegalArgumentException("timeoutMs must be positive, got " + t);
} Type guard
boolean positiveTimeout(FunctionConfig c) {
return c.getTimeoutMs() == null || c.getTimeoutMs() > 0;
} Try / catch
try {
admin.functions().updateFunction(functionConfig, configLocation);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("timeout must be a positive number")) {
// clear or correct timeoutMs and resubmit
}
throw e;
} Prevention
- Leave timeoutMs unset rather than 0 when no timeout is desired
- Parse durations into milliseconds carefully when converting from config files
- Validate timeoutMs > 0 in config generation code
- Pair timeout checks with processingGuarantees validation (see error 1417)
When it happens
Trigger: createFunction/updateFunction with functionConfig.getTimeoutMs() != null && timeoutMs <= 0: e.g. --timeout-ms 0 on the CLI, a variable defaulting to 0 assigned into the config, or a misparsed duration from YAML.
Common situations: Programmatic config where a Long timeout field defaults to 0, template placeholders like ${TIMEOUT_MS} resolved to empty/0, confusion between 'no timeout' (leave null) and 0.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Function config is not provided
- Output topic %s is also being used as an input topic (topics
- Input topic %s is invalid
- Output topic %s is invalid
- Function parallelism must be a positive number
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/6a76c30a004d75b6.
Report an issue: GitHub.