{"record":{"id":"0ec74b41d13ee559","repo":"apache/pulsar","slug":"interval-must-be-greater-than-or-equal-to-0","errorCode":null,"errorMessage":"interval must be greater than or equal to 0","messagePattern":"interval must be greater than or equal to 0","errorType":"validation","errorClass":"RestException","httpStatus":412,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/NamespacesBase.java","lineNumber":2445,"sourceCode":"                } else {\n                    int defaultNumberOfBundles = config().getDefaultNumberOfNamespaceBundles();\n                    policies.bundles = getBundles(defaultNumberOfBundles);\n                }\n\n                if (policies.persistence != null) {\n                    validatePersistencePolicies(policies.persistence);\n                }\n\n                if (policies.retention_policies != null) {\n                    validateRetentionPolicies(policies.retention_policies);\n                }\n            });\n    }\n\n    protected void internalSetDeduplicationSnapshotInterval(Integer interval) {\n        validateNamespacePolicyOperation(namespaceName, PolicyName.DEDUPLICATION_SNAPSHOT, PolicyOperation.WRITE);\n        if (interval != null && interval < 0) {\n            throw new RestException(Status.PRECONDITION_FAILED, \"interval must be greater than or equal to 0\");\n        }\n        internalSetPolicies(\"deduplicationSnapshotIntervalSeconds\", interval);\n    }\n\n    protected void internalSetMaxProducersPerTopic(Integer maxProducersPerTopic) {\n        validateNamespacePolicyOperation(namespaceName, PolicyName.MAX_PRODUCERS, PolicyOperation.WRITE);\n        validatePoliciesReadOnlyAccess();\n\n        try {\n            if (maxProducersPerTopic != null && maxProducersPerTopic < 0) {\n                throw new RestException(Status.PRECONDITION_FAILED,\n                        \"maxProducersPerTopic must be 0 or more\");\n            }\n            updatePolicies(namespaceName, policies -> {\n                policies.max_producers_per_topic = maxProducersPerTopic;\n                return policies;\n            });\n            log.info()","sourceCodeStart":2427,"sourceCodeEnd":2463,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/NamespacesBase.java#L2427-L2463","documentation":"Thrown by internalSetDeduplicationSnapshotInterval when setting the namespace deduplication snapshot interval to a negative value. The interval is a number of seconds between producer-dedup snapshots; only null (unset) or values >= 0 are allowed. Rejected with HTTP 412 PRECONDITION_FAILED before any policy update.","triggerScenarios":"POST /namespaces/{ns}/deduplicationSnapshotInterval with a negative integer; a caller passing -1 to mean 'disable' when the correct unset is null; config templates where an empty variable defaulted to a negative number.","commonSituations":"Scripts using -1 as a sentinel for 'disabled'; typos in generated config; CLI wrappers that don't validate the argument before calling the admin API.","solutions":["Pass a value >= 0 (0 can mean take snapshots as per default cadence, positive = interval seconds)","Use null (or omit the parameter) to clear/unset the interval instead of -1","Fix the source config/script that computed the negative value"],"exampleFix":"// before\nadmin.namespaces().setDeduplicationSnapshotInterval(\"my-tenant/my-ns\", -1); // 412\n// after\nadmin.namespaces().setDeduplicationSnapshotInterval(\"my-tenant/my-ns\", 10); // every 10s\n// or to unset:\nadmin.namespaces().setDeduplicationSnapshotInterval(\"my-tenant/my-ns\", null);","handlingStrategy":"validation","validationCode":"if (interval != null && interval < 0) {\n    throw new IllegalArgumentException(\"Deduplication snapshot interval must be >= 0 or null\");\n}","typeGuard":"boolean isValidInterval(Integer interval) { return interval == null || interval >= 0; }","tryCatchPattern":"try {\n    admin.namespaces().setDeduplicationSnapshotInterval(ns, interval);\n} catch (PulsarAdminException.PreconditionFailedException e) {\n    log.error(\"Interval {} invalid; pass null to unset\", interval);\n    throw e;\n}","preventionTips":["Treat null as the unset sentinel, not -1","Validate numeric args in CLI wrappers before API calls","Normalize empty config values to null instead of negative defaults"],"tags":["http-412","deduplication","validation","admin-api"],"backgroundTag":"invalid-policy-value","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}