apache/pulsar · error · IllegalArgumentException
Split service unit should be split into 2 service units.
Error message
Split service unit should be split into 2 service units.
What it means
The Split record models a topic-bundle split into exactly two child service units. Its compact constructor validates that splitServiceUnitToDestBroker is non-null with exactly 2 entries and throws IllegalArgumentException otherwise. It exists so callers cannot construct a malformed split plan.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/extensions/models/Split.java:34
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.pulsar.broker.loadbalance.extensions.models;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
/**
* Defines the information required for a service unit split(e.g. bundle split).
*/
public record Split(
String serviceUnit, String sourceBroker, Map<String, Optional<String>> splitServiceUnitToDestBroker) {
public Split {
Objects.requireNonNull(serviceUnit);
if (splitServiceUnitToDestBroker == null || splitServiceUnitToDestBroker.size() != 2) {
throw new IllegalArgumentException("Split service unit should be split into 2 service units.");
}
}
}
View on GitHub (pinned to 820761864e)
Solutions
- Compute exactly two child service units from the bundle's split point and map each to a destination broker before constructing Split.
- Use the standard split logic (e.g. TopicRanges/HierarchyTopicPolicies bundle split) so the two halves are always produced.
- Validate the destinations map size before constructing the record.
- Fix tests to supply a two-entry map.
Example fix
// before new Split(bundle, src, Map.of(firstHalf, destA)); // 1 entry -> throws // after new Split(bundle, src, Map.of(firstHalf, destA, secondHalf, destB)); // exactly 2 entries
Defensive patterns
Strategy: validation
Validate before calling
if (dests == null || dests.size() != 2) {
throw new IllegalArgumentException("split must yield exactly 2 units, got "
+ (dests == null ? 0 : dests.size()));
}
Split split = new Split(serviceUnit, sourceBroker, dests); Type guard
boolean isValidSplit(Split s) {
return s != null && s.splitServiceUnitToDestBroker() != null
&& s.splitServiceUnitToDestBroker().size() == 2;
} Try / catch
try {
Split split = new Split(serviceUnit, sourceBroker, dests);
} catch (IllegalArgumentException e) {
log.error("Bad split plan: {}", e.getMessage());
// skip/redo split computation
} Prevention
- Compute both halves of the bundle before building the Split record.
- Unit-test custom split-point logic to always produce two children.
- Validate destinations map size in any tooling that writes split plans.
When it happens
Trigger: Calling new Split(serviceUnit, sourceBroker, destinations) with a null map, or a map with 0, 1, or 3+ entries (split points must yield exactly two halves).
Common situations: Custom load-manager code computing split destinations produced one or more than two children, a migration/assignment tool wrote wrong data, or a unit test built a Split with a single destination.
Related errors
- Invalid range ${range}
- ResourceGroupCreate: Invalid null ResourceGroup config
- ResourceGroupCreate: can't create resource group with an emp
- ${name} is NULL, empty or contains a '&'
- failoverThreshold must be larger than 0
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/33140845f1420d05.
Report an issue: GitHub.