{"record":{"id":"48d2a8a079197449","repo":"apache/pulsar","slug":"e-getmessage","errorCode":null,"errorMessage":"${e.getMessage()}","messagePattern":"\\$\\{e\\.getMessage\\(\\)\\}","errorType":"http","errorClass":"RestException","httpStatus":412,"severity":"warning","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/ScalableTopics.java","lineNumber":610,"sourceCode":"                    // Validate the override in combination with the layers it will actually\n                    // be resolved with: the broker defaults AND the current namespace\n                    // override — two layers that are each valid against the defaults can\n                    // still combine into an invalid policy (e.g. the namespace raises a\n                    // merge threshold and the topic lowers the matching split threshold).\n                    // This check is best-effort: the namespace override can still change\n                    // afterwards, and broker defaults can differ across restarts — the\n                    // controller handles a combination that has become invalid by falling\n                    // back to disabled (see ScalableTopicController.resolveAutoScaleConfig).\n                    return pulsar().getPulsarResources().getNamespaceResources()\n                            .getPoliciesAsync(namespaceName)\n                            .thenAccept(optPolicies -> {\n                                AutoScalePolicyOverride nsOverride = optPolicies\n                                        .map(p -> p.scalableTopicAutoScalePolicy)\n                                        .orElse(null);\n                                try {\n                                    AutoScaleConfig.resolve(pulsar().getConfig(), nsOverride, override);\n                                } catch (IllegalArgumentException e) {\n                                    throw new RestException(Response.Status.PRECONDITION_FAILED,\n                                            e.getMessage());\n                                }\n                            });\n                })\n                .thenCompose(__ -> resources().updateScalableTopicAsync(tn, md -> {\n                    md.setAutoScalePolicy(override);\n                    return md;\n                }))\n                .thenAccept(__ -> {\n                    log.info().attr(\"clientAppId\", clientAppId()).attr(\"topic\", tn)\n                            .attr(\"removed\", override == null)\n                            .log(\"Updated autoScalePolicy on scalable topic\");\n                    asyncResponse.resume(Response.noContent().build());\n                })\n                .exceptionally(e -> {\n                    Throwable ex = FutureUtil.unwrapCompletionException(e);\n                    if (ex instanceof MetadataStoreException.NotFoundException) {\n                        asyncResponse.resume(new RestException(Response.Status.NOT_FOUND,","sourceCodeStart":592,"sourceCodeEnd":628,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/ScalableTopics.java#L592-L628","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n{\"minSegments\": 0, \"maxSegments\": 2}  // 412: minSegments must be >= 1\n// after\n{\"minSegments\": 1, \"maxSegments\": 8}","handlingStrategy":"validation","validationCode":"function validateAutoScalePolicy(p) {\n  if (!p || p.minSegments < 1 || p.maxSegments < p.minSegments) {\n    throw new Error('invalid auto-scale policy: need 1 <= minSegments <= maxSegments');\n  }\n}","typeGuard":"const isValidPolicy = (p) => p != null\n  && Number.isInteger(p.minSegments) && p.minSegments >= 1\n  && Number.isInteger(p.maxSegments) && p.maxSegments >= p.minSegments;","tryCatchPattern":"try {\n  await admin.scalableTopics().setAutoScalePolicy(tenant, ns, topic, policy);\n} catch (e) {\n  if (e.status === 412) console.error('Invalid policy:', e.message); // message is the resolver's reason\n  throw e;\n}","preventionTips":["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."],"tags":["rest","validation","auto-scaling","configuration","http-412"],"backgroundTag":"invalid-configuration-value","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}