openzipkin/zipkin · error · IllegalArgumentException

concurrency < 1

Error message

concurrency < 1

What it means

PulsarCollector.Builder.concurrency(Integer) throws IllegalArgumentException when the value is less than 1. Concurrency controls how many message consumers subscribe to the topic; zero or negative consumers is a misconfiguration. Note the parameter is boxed Integer, so passing null would instead cause an NPE during unboxing before this check.

Source

Thrown at zipkin-collector/pulsar/src/main/java/zipkin2/collector/pulsar/PulsarCollector.java:64

      this.metrics = metrics.forTransport("pulsar");
      this.delegate.metrics(this.metrics);
      return this;
    }

    @Override
    public Builder sampler(CollectorSampler sampler) {
      this.delegate.sampler(sampler);
      return this;
    }

    @Override
    public PulsarCollector build() {
      return new PulsarCollector(this);
    }

    /** Count of concurrent message consumers on the topic. Defaults to 1. */
    public Builder concurrency(Integer concurrency) {
      if (concurrency < 1) throw new IllegalArgumentException("concurrency < 1");
      this.concurrency = concurrency;
      return this;
    }

    /** Queue zipkin spans will be consumed from. Defaults to "zipkin". */
    public Builder topic(String topic) {
      if (StringUtils.isNullOrEmpty(topic)) throw new NullPointerException("topic is null or empty");
      this.topic = topic;
      return this;
    }

    /** The service URL for the Pulsar client ex. pulsar://my-broker:6650. No default. */
    public Builder serviceUrl(String serviceUrl) {
      if (StringUtils.isNullOrEmpty(serviceUrl)) throw new NullPointerException("serviceUrl is null or empty");
      clientProps.put("serviceUrl", serviceUrl);
      return this;
    }

View on GitHub (pinned to 878ce2a1fa)

Solutions

  1. Set concurrency to at least 1 (the default), e.g. .concurrency(Math.max(1, desired))
  2. Fix the source of the value: validate the env var / config key at startup
  3. If concurrency is optional, skip the call to keep the default of 1

Example fix

// before
builder.concurrency(Integer.getInteger("pulsar.concurrency", 0));

// after
builder.concurrency(Math.max(1, Integer.getInteger("pulsar.concurrency", 1)));
Defensive patterns

Strategy: validation

Validate before calling

int concurrency = Integer.parseInt(props.getProperty("pulsar.concurrency", "1"));
if (concurrency < 1) throw new IllegalStateException("pulsar.concurrency must be >= 1");
builder.concurrency(concurrency);

Prevention

When it happens

Trigger: Calling .concurrency(0) or .concurrency(-1), or computing concurrency from a config value/cpu formula that can evaluate to 0 (e.g. a percentage of cores rounded down).

Common situations: Sizing concurrency from environment variables (CONCURRENCY=0 in a staging config) or from a dynamic formula that returns 0 on small machines.

Related errors


AI-assisted analysis of openzipkin/zipkin@878ce2a1fa (2026-08-14). Data as JSON: /api/errors/02f3bf6328f962f5. Report an issue: GitHub.