neondatabase/neon · error

resource_multiplier must be between 0.0 and 1.0 exclusive, g

Error message

resource_multiplier must be between 0.0 and 1.0 exclusive, got {}

What it means

FileCacheConfig::validate enforces 0.0 < resource_multiplier < 1.0 strictly: the multiplier is the fraction of total memory the Postgres file cache may consume (default 0.75), and exactly 0 or 1 breaks the cache-sizing math. The check runs before any cache sizing happens.

Source

Thrown at libs/vm_monitor/src/filecache.rs:76

impl Default for FileCacheConfig {
    fn default() -> Self {
        Self {
            resource_multiplier: 0.75,
            // 256 MiB - lower than when in memory because overcommitting is safe; if we don't have
            // memory, the kernel will just evict from its page cache, rather than e.g. killing
            // everything.
            min_remaining_after_cache: NonZeroU64::new(256 * MiB).unwrap(),
            spread_factor: 0.1,
        }
    }
}

impl FileCacheConfig {
    /// Make sure fields of the config are consistent.
    pub fn validate(&self) -> anyhow::Result<()> {
        // Single field validity
        anyhow::ensure!(
            0.0 < self.resource_multiplier && self.resource_multiplier < 1.0,
            "resource_multiplier must be between 0.0 and 1.0 exclusive, got {}",
            self.resource_multiplier
        );
        anyhow::ensure!(
            self.spread_factor >= 0.0,
            "spread_factor must be >= 0, got {}",
            self.spread_factor
        );

        // Check that `resource_multiplier` and `spread_factor` are valid w.r.t. each other.
        //
        // As shown in `calculate_cache_size`, we have two lines resulting from `resource_multiplier` and
        // `spread_factor`, respectively. They are:
        //
        //                 `total`           `min_remaining_after_cache`
        //   size = ————————————————————— - —————————————————————————————
        //           `spread_factor` + 1         `spread_factor` + 1

View on GitHub (pinned to 8f60b04da4)

Solutions

  1. Set a value strictly inside (0.0, 1.0), e.g. 0.75
  2. If the value is a percentage, divide by 100 before assigning
  3. Call FileCacheConfig::validate() early at startup so config errors surface immediately

Example fix

// before
let config = FileCacheConfig { resource_multiplier: 1.0, ..Default::default() };
config.validate()?; // Err: must be between 0.0 and 1.0 exclusive
// after
let config = FileCacheConfig { resource_multiplier: 0.75, ..Default::default() };
config.validate()?; // Ok
Defensive patterns

Strategy: validation

Validate before calling

fn valid_resource_multiplier(v: f64) -> bool {
    v > 0.0 && v < 1.0
}

// check derived config before constructing/validating FileCacheConfig
anyhow::ensure!(valid_resource_multiplier(multiplier), "resource_multiplier must be in (0.0, 1.0), got {multiplier}");

Try / catch

if let Err(e) = config.validate() {
    if e.to_string().contains("resource_multiplier") {
        // config error: log the offending value and exit(1); do not fall back to defaults silently
    }
    return Err(e);
}

Prevention

When it happens

Trigger: Constructing FileCacheConfig with resource_multiplier of exactly 0.0 or 1.0, a negative number, or a value > 1, then calling validate() or building FileCacheState with it.

Common situations: Tuning vm_monitor file-cache sizing; config code passing a percentage as a raw number (75 instead of 0.75) or a sentinel like 0 meaning 'default'.

Related errors


AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16). Data as JSON: /api/errors/1ab94c41071c7500. Report an issue: GitHub.