apache/pulsar · error · IllegalArgumentException

Metrics port need to be within the range of 0 and 65535

Error message

Metrics port need to be within the range of 0 and 65535

What it means

In process mode (startProcessMode), when metricsPortStart is set, each instance i gets metricsPortStart + i. LocalRunner validates metricsPortStart is in [0, 65535] and throws IllegalArgumentException otherwise. Note the check happens after computing the port, and the range check is on the base port, not per-instance, so a high base can still overflow instance ports.

Source

Thrown at pulsar-functions/localrun/src/main/java/org/apache/pulsar/functions/LocalRunner.java:572

                null, /* extra dependencies dir */
                narExtractionDirectory, /* nar extraction dir */
                secretsProviderConfigurator,
                false, Optional.empty(), Optional.empty());

        for (int i = 0; i < parallelism; ++i) {
            InstanceConfig instanceConfig = new InstanceConfig();
            instanceConfig.setFunctionDetails(functionDetails);
            // TODO: correctly implement function version and id
            instanceConfig.setFunctionVersion(UUID.randomUUID().toString());
            instanceConfig.setFunctionId(UUID.randomUUID().toString());
            instanceConfig.setInstanceId(i + instanceIdOffset);
            instanceConfig.setMaxBufferedTuples(1024);
            instanceConfig.setPort(FunctionCommon.findAvailablePort());

            if (metricsPortStart != null) {
                int metricsPort = metricsPortStart + i;
                if (metricsPortStart < 0 || metricsPortStart > 65535) {
                    throw new IllegalArgumentException("Metrics port need to be within the range of 0 and 65535");
                }
                instanceConfig.setMetricsPort(metricsPort);
            } else {
                instanceConfig.setMetricsPort(FunctionCommon.findAvailablePort());
            }
            instanceConfig.setClusterName("local");
            if (functionConfig != null) {
                instanceConfig.setMaxPendingAsyncRequests(functionConfig.getMaxPendingAsyncRequests());
                if (functionConfig.getExposePulsarAdminClientEnabled() != null) {
                    instanceConfig
                            .setExposePulsarAdminClientEnabled(functionConfig.getExposePulsarAdminClientEnabled());
                }
            }

            RuntimeSpawner runtimeSpawner = new RuntimeSpawner(
                    instanceConfig,
                    userCodeFile,
                    null,

View on GitHub (pinned to 820761864e)

Solutions

  1. Set metricsPortStart to a value between 0 and 65535 (with headroom for parallelism instances)
  2. Leave metricsPortStart null to let the runner pick available ports automatically
  3. Validate the env/property driving this value before setting it

Example fix

// before
runner.setMetricsPortStart(Integer.parseInt(env.get("METRICS_PORT"))); // env missing -> -1?
// after
int port = Integer.parseInt(env.getOrDefault("METRICS_PORT", "0"));
if (port < 0 || port > 65535) {
    throw new IllegalArgumentException("METRICS_PORT out of range");
}
runner.setMetricsPortStart(port);
Defensive patterns

Strategy: validation

Validate before calling

if (metricsPortStart != null && (metricsPortStart < 0 || metricsPortStart > 65535)) {
    throw new IllegalArgumentException("metricsPortStart must be 0-65535");
}
runner.setMetricsPortStart(metricsPortStart);

Try / catch

try {
    runner.start(true);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Metrics port")) {
        // correct metricsPortStart and restart with a new runner
    }
}

Prevention

When it happens

Trigger: Starting LocalRunner with setMetricsPortStart(-1) or a value > 65535 in process runtime mode.

Common situations: Misconfigured port derived from an env variable (empty/-1); copy-paste of an instance index into the base port field; port collisions prompting users to guess large values.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/5086f43b481ecc27. Report an issue: GitHub.