apache/pulsar · error · RestException

Retention Quota must exceed configured backlog quota for nam

Error message

Retention Quota must exceed configured backlog quota for namespace.

What it means

Thrown by setRetention for a namespace: the broker validates that the retention quota being set is strictly greater than the namespace's configured backlog quota (checkQuotas). If not, the update is rejected with HTTP 412 PRECONDITION_FAILED, because a backlog quota larger than retention would create contradictory data-retention semantics.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/NamespacesBase.java:1913

            policies.backlog_quota_map.put(quotaType, quota);
            return policies;
        });
    }

    protected void internalSetRetention(RetentionPolicies retention) {
        validateRetentionPolicies(retention);
        validateNamespacePolicyOperation(namespaceName, PolicyName.RETENTION, PolicyOperation.WRITE);
        validatePoliciesReadOnlyAccess();

        try {
            Policies policies = namespaceResources().getPolicies(namespaceName)
                    .orElseThrow(() -> new RestException(Status.NOT_FOUND,
                    "Namespace policies does not exist"));
            if (!checkQuotas(policies, retention)) {
                log.warn()
                        .attr("namespace", namespaceName)
                        .log("Failed to update retention configuration for namespace: conflicts with backlog quota");
                throw new RestException(Status.PRECONDITION_FAILED,
                        "Retention Quota must exceed configured backlog quota for namespace.");
            }
            policies.retention_policies = retention;
            namespaceResources().setPolicies(namespaceName, p -> policies);
            log.info()
                    .attr("namespace", namespaceName)
                    .attr("retention", objectWriter().writeValueAsString(retention))
                    .log("Successfully updated retention configuration");
        } catch (RestException pfe) {
            throw pfe;
        } catch (Exception e) {
            log.error()
                    .attr("namespace", namespaceName)
                    .exception(e)
                    .log("Failed to update retention configuration for namespace");
            throw new RestException(e);
        }
    }

View on GitHub (pinned to 820761864e)

Solutions

  1. Increase the retention policies values so the retention quota exceeds the configured backlog quota
  2. First lower or remove the backlog quota (setBacklogQuota with null or smaller value), then set retention
  3. Inspect current policies (getBacklogQuotaMap and getRetention) and pick consistent values
  4. Apply quota changes in order: backlog quota down before retention down

Example fix

// before
admin.namespaces().setBacklogQuota("my-tenant/my-ns", new BacklogQuota(1_000_000_000L, ...));
admin.namespaces().setRetention("my-tenant/my-ns", new RetentionPolicies(500_000_000L, 30)); // 412
// after
admin.namespaces().setRetention("my-tenant/my-ns", new RetentionPolicies(2_000_000_000L, 120)); // retention > backlog
Defensive patterns

Strategy: validation

Validate before calling

Map<BacklogQuotaType, BacklogQuota> quotas = admin.namespaces().getBacklogQuotaMap(ns);
long maxBacklog = quotas.values().stream().mapToLong(BacklogQuota::getLimitSize).max().orElse(0);
if (retention.getRetentionSizeInMB() * 1024L * 1024L <= maxBacklog) {
    throw new IllegalArgumentException("Retention must exceed configured backlog quota; lower backlog first");
}

Try / catch

try {
    admin.namespaces().setRetention(ns, retention);
} catch (PulsarAdminException.PreconditionFailedException e) {
    admin.namespaces().setBacklogQuota(ns, smallerQuota, BacklogQuotaType.destination_storage);
    admin.namespaces().setRetention(ns, retention);
}

Prevention

When it happens

Trigger: POST /namespaces/{ns}/retention with a retention size/time smaller than (or equal to a conflicting) backlog quota already configured via setBacklogQuota; lowering retention on a namespace that has a large destination_storage backlog quota.

Common situations: Reducing retention to save storage while an old large backlog quota remains; migrating namespaces between tenants with different quota defaults; automation that sets retention before clearing backlog quotas.

Related errors


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