apache/pulsar · error · PulsarServerException
javaInstanceRunnable is not initialized
Error message
javaInstanceRunnable is not initialized
What it means
ThreadRuntime.getPrometheusMetrics() returns the Java instance's stats as a Prometheus string, but this only works after the instance runnable has been created/started. If javaInstanceRunnable is still null (getPrometheusMetrics called before the thread instance finished initializing), it throws PulsarServerException('javaInstanceRunnable is not initialized').
Source
Thrown at pulsar-functions/runtime/src/main/java/org/apache/pulsar/functions/runtime/thread/ThreadRuntime.java:311
statsFuture.complete(functionStatus);
return statsFuture;
}
@Override
public CompletableFuture<MetricsData> getAndResetMetrics() {
return CompletableFuture.completedFuture(javaInstanceRunnable.getAndResetMetrics());
}
@Override
public CompletableFuture<MetricsData> getMetrics(int instanceId) {
return CompletableFuture.completedFuture(javaInstanceRunnable.getMetrics());
}
@Override
public String getPrometheusMetrics() throws IOException {
if (javaInstanceRunnable == null) {
throw new PulsarServerException("javaInstanceRunnable is not initialized");
}
return javaInstanceRunnable.getStatsAsString();
}
@Override
public CompletableFuture<Void> resetMetrics() {
javaInstanceRunnable.resetMetrics();
return CompletableFuture.completedFuture(null);
}
@Override
public boolean isAlive() {
if (this.fnThread != null) {
return this.fnThread.isAlive();
} else {
return false;
}
}View on GitHub (pinned to 820761864e)
Solutions
- Ensure the function instance has fully started before scraping its Prometheus metrics (retry the metrics call after startup completes).
- Investigate why initialization never created javaInstanceRunnable (check earlier instance startup errors in the worker log).
- Handle PulsarServerException from the metrics endpoint and treat it as retryable/until-ready.
- In code, guard calls so getPrometheusMetrics is only invoked on a started ThreadRuntime.
Example fix
// before
String metrics = threadRuntime.getPrometheusMetrics();
// after
try {
String metrics = threadRuntime.getPrometheusMetrics();
} catch (PulsarServerException e) {
// instance not started yet; retry after startup or skip this scrape
} Defensive patterns
Strategy: try-catch
Validate before calling
// only call after the instance has started; expose/check a started flag if you own the lifecycle
if (!instanceStarted) {
throw new IllegalStateException("call getPrometheusMetrics only after ThreadRuntime.start() completed");
} Try / catch
try {
String metrics = threadRuntime.getPrometheusMetrics();
} catch (PulsarServerException e) {
if (e.getMessage() != null && e.getMessage().contains("javaInstanceRunnable is not initialized")) {
// instance not started yet: retry after startup or skip this scrape
} else {
throw e;
}
} Prevention
- Delay metrics scraping until the function instance reports started/running.
- Monitor instance startup failures — a null runnable means initialization never completed.
- Make metrics scrapers tolerant of a 'not ready' window after function assignment.
When it happens
Trigger: Calling getPrometheusMetrics() (e.g. via the worker's metrics/promise endpoint) on a ThreadRuntime whose start() has not yet constructed javaInstanceRunnable, or after initialization failed before runnable creation.
Common situations: Metrics scrapers hitting the function worker immediately after function assignment, racing instance startup; function instance failed to initialize leaving the runtime half-constructed; tests or tooling invoking getPrometheusMetrics() on a freshly created ThreadRuntime.
Related errors
- Unknown component type: %s
- The log error handler cannot be changed once the appender is
- FunctionArchive is already closed
- Connector is already closed
- Worker ${workerId} was not yet removed after a prior drain o
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/9fc3be0cac7a2732.
Report an issue: GitHub.