apache/pulsar · warning · RestException
${e.getMessage()}
Error message
${e.getMessage()} What it means
HTTP 412 PRECONDITION_FAILED wrapping an IllegalArgumentException from AutoScaleConfig.resolve when the requested auto-scale policy override is invalid (bad field values or a combination not permitted given broker config / namespace override). The policy is validated before being persisted and the underlying resolver's message is propagated verbatim.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/ScalableTopics.java:610
// Validate the override in combination with the layers it will actually
// be resolved with: the broker defaults AND the current namespace
// override — two layers that are each valid against the defaults can
// still combine into an invalid policy (e.g. the namespace raises a
// merge threshold and the topic lowers the matching split threshold).
// This check is best-effort: the namespace override can still change
// afterwards, and broker defaults can differ across restarts — the
// controller handles a combination that has become invalid by falling
// back to disabled (see ScalableTopicController.resolveAutoScaleConfig).
return pulsar().getPulsarResources().getNamespaceResources()
.getPoliciesAsync(namespaceName)
.thenAccept(optPolicies -> {
AutoScalePolicyOverride nsOverride = optPolicies
.map(p -> p.scalableTopicAutoScalePolicy)
.orElse(null);
try {
AutoScaleConfig.resolve(pulsar().getConfig(), nsOverride, override);
} catch (IllegalArgumentException e) {
throw new RestException(Response.Status.PRECONDITION_FAILED,
e.getMessage());
}
});
})
.thenCompose(__ -> resources().updateScalableTopicAsync(tn, md -> {
md.setAutoScalePolicy(override);
return md;
}))
.thenAccept(__ -> {
log.info().attr("clientAppId", clientAppId()).attr("topic", tn)
.attr("removed", override == null)
.log("Updated autoScalePolicy on scalable topic");
asyncResponse.resume(Response.noContent().build());
})
.exceptionally(e -> {
Throwable ex = FutureUtil.unwrapCompletionException(e);
if (ex instanceof MetadataStoreException.NotFoundException) {
asyncResponse.resume(new RestException(Response.Status.NOT_FOUND,View on GitHub (pinned to 820761864e)
Solutions
- Read the error message (it is the resolver's IllegalArgumentException text) and correct the offending policy field(s).
- Inspect the broker's scalable-topic auto-scale configuration and the namespace-level scalableTopicAutoScalePolicy override to see the allowed ranges/combination.
- Validate the policy against AutoScaleConfig.resolve semantics client-side before issuing the call.
Example fix
// before
{"minSegments": 0, "maxSegments": 2} // 412: minSegments must be >= 1
// after
{"minSegments": 1, "maxSegments": 8} Defensive patterns
Strategy: validation
Validate before calling
function validateAutoScalePolicy(p) {
if (!p || p.minSegments < 1 || p.maxSegments < p.minSegments) {
throw new Error('invalid auto-scale policy: need 1 <= minSegments <= maxSegments');
}
} Type guard
const isValidPolicy = (p) => p != null && Number.isInteger(p.minSegments) && p.minSegments >= 1 && Number.isInteger(p.maxSegments) && p.maxSegments >= p.minSegments;
Try / catch
try {
await admin.scalableTopics().setAutoScalePolicy(tenant, ns, topic, policy);
} catch (e) {
if (e.status === 412) console.error('Invalid policy:', e.message); // message is the resolver's reason
throw e;
} Prevention
- Mirror AutoScaleConfig validation rules client-side before calling the API.
- Check broker scalable-topic config and namespace-level overrides for constrained ranges.
- Reuse the same policy object validated once across environments.
When it happens
Trigger: Calling PUT/DELETE on /{tenant}/{namespace}/{topic}/autoScalePolicy with an AutoScalePolicy body whose values fail AutoScaleConfig.resolve — e.g. out-of-range thresholds, invalid scaling factor, or a value incompatible with broker/namespace-level settings.
Common situations: Copy-pasting a policy JSON from docs with values outside broker-configured min/max; namespace-level policy restricting what topic-level overrides may set; typos in unit or enum fields; API clients sending 0/negative values where positive are required.
Understand the failure class
Background: "Invalid configuration value" and "Unsupported/Unknown setting value" errors: why libraries reject your config strings, numbers, and types — this error's family across 30 libraries.
Related errors
- numInitialSegments must be >= 1
- Timeout during delete operation
- Timeout during close operation
- Timeout during open-cursor operation
- Timeout during delete-cursors operation
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/48d2a8a079197449.
Report an issue: GitHub.