{"record":{"id":"bfd5c691317d5841","repo":"chroma-core/chroma","slug":"bucket-name-capacity-and-interval-ns-must-be-positive-and","errorCode":null,"errorMessage":"bucket {name:?}: capacity and interval_ns must be positive and their product must fit in u64","messagePattern":"bucket (.+?): capacity and interval_ns must be positive and their product must fit in u64","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"rust/mdac-service/src/lib.rs","lineNumber":83,"sourceCode":"            config = config.merge(Yaml::file(path));\n        }\n        config\n            .merge(Env::prefixed(\"MDAC_\"))\n            .extract()\n            .map_err(Box::new)\n    }\n\n    /// Validate all rates and construct every configured bucket with a full allowance.\n    pub fn buckets(&self) -> io::Result<Arc<TokenBuckets>> {\n        for (name, config) in &self.buckets {\n            if config.capacity == 0\n                || config.interval_ns == 0\n                || config\n                    .interval_ns\n                    .checked_mul(u64::from(config.capacity))\n                    .is_none()\n            {\n                return Err(io::Error::new(\n                    io::ErrorKind::InvalidInput,\n                    format!(\"bucket {name:?}: capacity and interval_ns must be positive and their product must fit in u64\"),\n                ));\n            }\n        }\n        Ok(Arc::new(TokenBuckets {\n            buckets: self\n                .buckets\n                .iter()\n                .map(|(name, config)| {\n                    (\n                        name.clone(),\n                        TokenBucket::new(config.capacity, Duration::from_nanos(config.interval_ns)),\n                    )\n                })\n                .collect(),\n        }))\n    }","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/chroma-core/chroma/blob/a7920e95c184ba9243165931e65c8e01c67c06f5/rust/mdac-service/src/lib.rs#L65-L101","documentation":"This error is returned by Config::buckets() in rust/mdac-service/src/lib.rs:83 when a configured token-bucket definition fails validation. A bucket's capacity (u32) and interval_ns (u64) must each be strictly positive, and their product (capacity * interval_ns, i.e. the total refill duration) must not overflow u64. The check uses checked_mul, so any overflow or zero value for either field aborts construction of the bucket set with io::ErrorKind::InvalidInput.","triggerScenarios":"Calling Config::buckets() when any entry in self.buckets has capacity == 0, interval_ns == 0, or interval_ns * capacity (as u64) > u64::MAX. Values come from YAML config merged with MDAC_-prefixed environment overrides via figment, so a bad YAML bucket entry or an env var like MDAC_BUCKETS_<NAME>_INTERVAL_NS set to 0 or an enormous number triggers it.","commonSituations":"Typo in a YAML bucket config leaving capacity unset/0; an environment override setting interval_ns to 0; copy-pasting an interval like 1e18 ns per token with a large capacity so the product overflows u64; converting from a seconds-based config to nanoseconds and multiplying by 1_000_000_000, pushing the product past u64::MAX.","solutions":["Inspect the failing bucket name in the error message and fix its capacity to be >= 1 in the YAML config or MDAC_ env override.","Set interval_ns to a positive value; remember it is nanoseconds per token, not total refill time.","Reduce capacity or interval_ns so their product fits in u64 (max ~1.8e19); e.g. prefer smaller capacity with proportionally scaled intervals.","Add pre-startup validation of the buckets config section so misconfiguration is caught before Config::buckets() is called."],"exampleFix":"// before (config.yaml)\nbuckets:\n  api:\n    capacity: 0\n    interval_ns: 1_000_000_000\n\n// after\nbuckets:\n  api:\n    capacity: 10\n    interval_ns: 1_000_000_000","handlingStrategy":"validation","validationCode":"fn validate_bucket(name: &str, capacity: u32, interval_ns: u64) -> Result<(), String> {\n    if capacity == 0 {\n        return Err(format!(\"bucket {name}: capacity must be > 0\"));\n    }\n    if interval_ns == 0 {\n        return Err(format!(\"bucket {name}: interval_ns must be > 0\"));\n    }\n    interval_ns\n        .checked_mul(u64::from(capacity))\n        .ok_or_else(|| format!(\"bucket {name}: capacity * interval_ns overflows u64\"))?;\n    Ok(())\n}","typeGuard":"fn is_valid_bucket(capacity: u32, interval_ns: u64) -> bool {\n    capacity > 0\n        && interval_ns > 0\n        && interval_ns.checked_mul(u64::from(capacity)).is_some()\n}","tryCatchPattern":"let buckets = config.buckets().map_err(|e| {\n    eprintln!(\"invalid rate-limit bucket config: {e}\");\n    std::process::exit(2);\n});","preventionTips":["Never set capacity or interval_ns to 0 in bucket YAML or MDAC_ env overrides.","Compute interval_ns as nanoseconds per token; if you think in seconds, multiply by 1_000_000_000 and re-check overflow with capacity.","Keep capacity * interval_ns below u64::MAX (about 1.8e19) when sizing buckets.","Add a unit test that builds Config::buckets() for your production config file in CI."],"tags":["rust","config","rate-limiting","validation","overflow"],"backgroundTag":"invalid-config-value","analyzedSha":"a7920e95c184ba9243165931e65c8e01c67c06f5","analyzedAt":"2026-09-12T09:43:55.728Z","contentChangedAt":"2026-09-12T09:43:55.728Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}