{"record":{"id":"3b6f9ccacdc056b6","repo":"rustfs/rustfs","slug":"object-data-cache-could-not-resolve-a-positive-max","errorCode":null,"errorMessage":"object data cache could not resolve a positive max capacity","messagePattern":"object data cache could not resolve a positive max capacity","errorType":"validation","errorClass":"ObjectDataCacheConfigError","httpStatus":null,"severity":"error","filePath":"crates/object-data-cache/src/error.rs","lineNumber":81,"sourceCode":"\n    /// The configured fill concurrency maximum exceeded the supported range.\n    #[error(\"object data cache fill_concurrency_max must be greater than 0\")]\n    ZeroFillConcurrencyMax,\n\n    /// The configured fill concurrency bounds are internally inconsistent.\n    #[error(\"object data cache fill_concurrency_max must be at least fill_concurrency_per_cpu\")]\n    FillConcurrencyMaxTooSmall,\n\n    /// The configured identity key-set cap exceeded the supported range.\n    #[error(\"object data cache identity_keys_max must be greater than 0\")]\n    ZeroIdentityKeysMax,\n\n    /// A single-key identity budget evicts the previous key on every fill.\n    #[error(\"object data cache identity_keys_max must be at least 2\")]\n    IdentityKeysMaxTooSmall,\n\n    /// Failed to resolve a non-zero cache capacity from the runtime environment.\n    #[error(\"object data cache could not resolve a positive max capacity\")]\n    ZeroResolvedMaxBytes,\n}\n","sourceCodeStart":63,"sourceCodeEnd":84,"githubUrl":"https://github.com/rustfs/rustfs/blob/35af688cd9d41b4346fbe27dcf7250ba72046c1f/crates/object-data-cache/src/error.rs#L63-L84","documentation":"ObjectDataCacheConfigError::ZeroResolvedMaxBytes is returned by ObjectDataCacheConfig::resolved_max_bytes() (crates/object-data-cache/src/config.rs:165) when max_bytes is left at 0 and the capacity derived from the runtime environment resolves to zero. The derivation is effective (container/cgroup-aware) total memory multiplied by max_memory_percent, then clamped; if the effective memory query reports 0 or the derived value floors to 0, the cache cannot size itself and fails fast instead of starting with no capacity.","triggerScenarios":"Calling resolved_max_bytes() (directly or via moka backend construction) with max_bytes == 0 while resolve_effective_memory() returns a total of 0 — e.g. sysinfo cannot read cgroup memory limits, or an extremely small max_memory_percent makes total*percent/100 saturate to 0.","commonSituations":"Containers with unusual or missing cgroup v2 memory.max; sandboxes/CI where memory detection fails; misconfigured max_memory_percent far below 1% of a tiny total; hosts where /proc or /sys are masked.","solutions":["Set an explicit capacity: config.max_bytes = 512 * 1024 * 1024; so resolution never depends on the environment","Raise max_memory_percent (e.g. to the default) so the derived value is non-zero on the detected total memory","If running in a container, verify the cgroup memory limit is visible (docker --memory, Kubernetes resources.limits.memory) and not set to 0/unlimited in a way sysinfo reports as zero","Check that /proc/meminfo and /sys/fs/cgroup are mounted and readable in the runtime environment"],"exampleFix":"// before\nlet config = ObjectDataCacheConfig::default(); // max_bytes = 0, derive from memory\nlet cap = config.resolved_max_bytes()?; // Err(ZeroResolvedMaxBytes) on hosts reporting 0\n\n// after\nlet mut config = ObjectDataCacheConfig::default();\nconfig.max_bytes = 512 * 1024 * 1024; // explicit capacity, no env dependency\nlet cap = config.resolved_max_bytes()?; // Ok(512 MiB)","handlingStrategy":"validation","validationCode":"// Fail fast with a clear message instead of relying on env detection:\nfn resolve_capacity(cfg: &ObjectDataCacheConfig) -> Result<u64, Box<dyn std::error::Error>> {\n    if cfg.max_bytes == 0 && resolve_effective_memory_total() == 0 {\n        return Err(\"environment reports 0 total memory; set max_bytes explicitly\".into());\n    }\n    Ok(cfg.resolved_max_bytes()?)\n}","typeGuard":null,"tryCatchPattern":"match config.resolved_max_bytes() {\n    Ok(bytes) => build_cache(bytes)?,\n    Err(ObjectDataCacheConfigError::ZeroResolvedMaxBytes) => {\n        // deterministic fallback: explicit capacity, no silent zero-byte cache\n        let mut fixed = config.clone();\n        fixed.max_bytes = 256 * 1024 * 1024;\n        build_cache(fixed.resolved_max_bytes()?)?\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Pin an explicit max_bytes in containers so capacity never depends on cgroup detection","Smoke-test deployments with a startup probe that calls resolved_max_bytes() and fails fast","Keep max_memory_percent at sane values (>= 1) and monitor effective-memory detection in new base images"],"tags":["rust","object-data-cache","memory-sizing","containers","cgroup"],"backgroundTag":"environment-capacity-detection-failed","analyzedSha":"35af688cd9d41b4346fbe27dcf7250ba72046c1f","analyzedAt":"2026-08-20T21:57:04.799Z","contentChangedAt":"2026-08-20T21:57:04.799Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}