apache/pulsar · error · IllegalArgumentException
Late data topic can be defined only when specifying a timest
Error message
Late data topic can be defined only when specifying a timestamp extractor class
What it means
A late-data topic lets the executor route records arriving after the watermark, but routing them correctly requires a custom timestamp extractor to know each record's event time. getWindowManager throws this IllegalArgumentException if lateDataTopic is set in WindowConfig while timestampExtractorClassName is null. The configuration is internally inconsistent, so initialization fails.
Source
Thrown at pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutor.java:115
WindowConfig.class);
return windowConfig;
}
private WindowManager<Record<T>> getWindowManager(WindowConfig windowConfig, Context context) {
WindowLifecycleListener<Event<Record<T>>> lifecycleListener = newWindowLifecycleListener(context);
WindowManager<Record<T>> manager = new WindowManager<>(lifecycleListener, new ConcurrentLinkedQueue<>());
if (this.windowConfig.getTimestampExtractorClassName() != null) {
this.timestampExtractor = getTimeStampExtractor(windowConfig);
waterMarkEventGenerator = new WaterMarkEventGenerator<>(manager, this.windowConfig
.getWatermarkEmitIntervalMs(),
this.windowConfig.getMaxLagMs(), new HashSet<>(context.getInputTopics()), context);
} else {
if (this.windowConfig.getLateDataTopic() != null) {
throw new IllegalArgumentException(
"Late data topic can be defined only when specifying a timestamp extractor class");
}
}
EvictionPolicy<Record<T>, ?> evictionPolicy = getEvictionPolicy(windowConfig);
TriggerPolicy<Record<T>, ?> triggerPolicy = getTriggerPolicy(windowConfig, manager,
evictionPolicy, context);
manager.setEvictionPolicy(evictionPolicy);
manager.setTriggerPolicy(triggerPolicy);
return manager;
}
@SuppressWarnings("unchecked")
private TimestampExtractor<T> getTimeStampExtractor(WindowConfig windowConfig) {
Class<?> theCls;
try {View on GitHub (pinned to 820761864e)
Solutions
- Set timestampExtractorClassName in WindowConfig to a class implementing org.apache.pulsar.functions.api.windowing.TimestampExtractor
- Or remove lateDataTopic from WindowConfig if you don't need late-data routing (late events are then dropped by the eviction policy)
- Rebuild and redeploy the function with the corrected window config
- Document the extractor class and ensure its jar is bundled with the function
Example fix
// before
userConfig: { "windowConfig": { "windowLengthDurationMs": 60000, "lateDataTopic": "late-topic" } }
// after
userConfig: { "windowConfig": { "windowLengthDurationMs": 60000, "lateDataTopic": "late-topic",
"timestampExtractorClassName": "com.example.MyTimestampExtractor" } } Defensive patterns
Strategy: validation
Validate before calling
WindowConfig wc = ...;
if (wc.getLateDataTopic() != null && wc.getTimestampExtractorClassName() == null) {
throw new IllegalArgumentException("lateDataTopic requires timestampExtractorClassName");
} Try / catch
try {
executor.initialize();
} catch (IllegalArgumentException e) {
throw new IllegalStateException("inconsistent window config: " + e.getMessage(), e);
} Prevention
- Treat lateDataTopic and timestampExtractorClassName as a pair in config templates
- Drop lateDataTopic if you rely on ingestion-time timestamps
- Validate window config JSON in CI before deploying
When it happens
Trigger: WindowConfig supplied with lateDataTopic non-null but timestampExtractorClassName not set; typically a copy-pasted window config where the extractor class was removed or never added.
Common situations: Users enabling late-data handling for out-of-order events but relying on the default ingestion-time timestamps; config template stripping the extractor class name; switching from ingestion-time to event-time semantics without cleaning lateDataTopic.
Related errors
- Window function must take a collection as input
- Window function does not implement the correct interface
- Window Configs cannot be found
- Timestamp extractor class %s must be in class path
- User class must be concrete
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/4bd0b8aaac9043bf.
Report an issue: GitHub.