apache/pulsar · error · IllegalArgumentException

Namespace ${namespace} does not match policy

Error message

Namespace ${namespace} does not match policy

What it means

NamespaceIsolationPolicyImpl.findPrimaryBrokers() first verifies the given namespace actually falls under this policy's namespace regex list. If matchNamespaces() fails, the policy is being applied to a namespace it doesn't own, so it throws IllegalArgumentException instead of returning an empty broker list. This guards against silently wrong failover decisions.

Source

Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/policies/impl/NamespaceIsolationPolicyImpl.java:90

    @Override
    public List<String> getPrimaryBrokers() {
        return this.primary;
    }

    @Override
    public List<String> getSecondaryBrokers() {
        return this.secondary;
    }

    @Override
    public NamespaceIsolationPolicyUnloadScope getUnloadScope() {
        return this.unloadScope;
    }

    @Override
    public List<URL> findPrimaryBrokers(List<URL> availableBrokers, NamespaceName namespace) {
        if (!this.matchNamespaces(namespace.toString())) {
            throw new IllegalArgumentException("Namespace " + namespace.toString() + " does not match policy");
        }
        // find the available brokers that matches primary brokers regex list
        return this.getMatchedBrokers(this.primary, availableBrokers);
    }

    @Override
    public List<URL> findSecondaryBrokers(List<URL> availableBrokers, NamespaceName namespace) {
        if (!this.matchNamespaces(namespace.toString())) {
            throw new IllegalArgumentException("Namespace " + namespace.toString() + " does not match policy");
        }
        // find the available brokers that matches primary brokers regex list
        return this.getMatchedBrokers(this.secondary, availableBrokers);
    }

    @Override
    public boolean shouldFallback(SortedSet<BrokerStatus> primaryBrokers) {
        // TODO Auto-generated method stub
        return false;

View on GitHub (pinned to 820761864e)

Solutions

  1. Select the policy via namespaceIsolationPolicies.getPolicy(namespace) (which matches by regex) instead of applying an arbitrary policy object
  2. Fix the namespace string passed in (full form: tenant/cluster/namespace)
  3. Update the policy's namespace regex to cover the namespace in question
  4. Add a matchNamespaces() check in caller code before invoking findPrimaryBrokers

Example fix

// before
policy.findPrimaryBrokers(brokers, ns); // policy may not cover ns
// after
if (policy != null && policy.matchNamespaces(ns.toString())) {
    policy.findPrimaryBrokers(brokers, ns);
}
Defensive patterns

Strategy: validation

Validate before calling

// Only call findPrimaryBrokers on a policy that actually matches the namespace
if (policy == null || !policy.matchNamespaces(ns.toString())) {
    throw new IllegalStateException("Policy does not govern namespace " + ns);
}

Type guard

static boolean policyCovers(NamespaceIsolationPolicyImpl p, NamespaceName ns) {
    return p != null && p.matchNamespaces(ns.toString());
}

Try / catch

try {
    List<URL> primaries = policy.findPrimaryBrokers(brokers, ns);
} catch (IllegalArgumentException e) {
    log.warn("Namespace {} not covered by this policy; resolving by match instead", ns);
    policy = nsPolicies.getPolicy(ns); // re-resolve correct policy
}

Prevention

When it happens

Trigger: Calling findPrimaryBrokers(availableBrokers, namespace) with a namespace string that matches none of the policy's 'namespaces?' regexes — typically by looking up a policy via a regex-keyed map and querying it with a different namespace.

Common situations: iterating all policies and applying each to one namespace; namespace renamed/created after policies were defined; case or tenant/cluster prefix mismatch between policy pattern and namespace string.

Related errors


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