neondatabase/neon · error

Unknown scheduling policy '{s}', try active,pause,decomissio

Error message

Unknown scheduling policy '{s}', try active,pause,decomissioned

What it means

SkSchedulingPolicy::from_str rejects any string that is not one of the storage controller's tenant scheduling policies. The accepted literals are 'active', 'activating', 'pause', and 'decomissioned' -- note the single-'m' spelling of 'decomissioned' is the one the code matches. The error hint text lists only three of the four; 'activating' is also valid input.

Source

Thrown at libs/pageserver_api/src/controller_api.rs:454

#[derive(Serialize, Deserialize, Clone, Copy, Eq, PartialEq, Debug)]
pub enum SkSchedulingPolicy {
    Active,
    Activating,
    Pause,
    Decomissioned,
}

impl FromStr for SkSchedulingPolicy {
    type Err = anyhow::Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(match s {
            "active" => Self::Active,
            "activating" => Self::Activating,
            "pause" => Self::Pause,
            "decomissioned" => Self::Decomissioned,
            _ => {
                return Err(anyhow::anyhow!(
                    "Unknown scheduling policy '{s}', try active,pause,decomissioned"
                ));
            }
        })
    }
}

impl From<SkSchedulingPolicy> for String {
    fn from(value: SkSchedulingPolicy) -> String {
        use SkSchedulingPolicy::*;
        match value {
            Active => "active",
            Activating => "activating",
            Pause => "pause",
            Decomissioned => "decomissioned",
        }
        .to_string()
    }

View on GitHub (pinned to 8f60b04da4)

Solutions

  1. Use exactly one of: active, activating, pause, decomissioned (single m)
  2. For decommissioning, mirror the literal in the error hint: 'decomissioned'
  3. Compare against the SkSchedulingPolicy FromStr impl in your checkout/release; the policy set changes between versions
  4. Trim whitespace and avoid quoting the value; URL-encode it when sent via query string

Example fix

# before
curl -X PUT 'http://localhost:1234/control/v1/tenant/68d.../scheduling?policy=decommissioned'
# -> Unknown scheduling policy 'decommissioned', try active,pause,decomissioned

# after (note the single-m spelling)
curl -X PUT 'http://localhost:1234/control/v1/tenant/68d.../scheduling?policy=decomissioned'
Defensive patterns

Strategy: type-guard

Validate before calling

const SK_SCHEDULING_POLICIES: &[&str] = &["active", "activating", "pause", "decomissioned"];

fn validate_policy(policy: &str) -> Result<(), String> {
    if SK_SCHEDULING_POLICIES.contains(&policy) {
        Ok(())
    } else {
        Err(format!(
            "invalid scheduling policy {policy:?}; expected one of {SK_SCHEDULING_POLICIES:?} \
             (note: 'decomissioned' is spelled with a single m)"
        ))
    }
}

Type guard

fn is_valid_sk_scheduling_policy(s: &str) -> bool {
    matches!(s, "active" | "activating" | "pause" | "decomissioned")
}

Try / catch

match SkSchedulingPolicy::from_str(policy) {
    Ok(p) => p,
    Err(e) => {
        // FromStr has no typed error; match on the message and re-raise with the valid set
        if e.to_string().starts_with("Unknown scheduling policy") {
            return Err(anyhow::anyhow!("{e}; valid: active, activating, pause, decomissioned"));
        }
        return Err(e);
    }
}

Prevention

When it happens

Trigger: PUT/GET on the storage controller scheduling-policy API or the neon CLI equivalent with an unsupported value: 'decommissioned' (correct English spelling), 'paused', 'disabled', 'drain', 'ACTIVE', or trailing whitespace/quotes around the value. Example: 'curl -X PUT .../control/v1/tenant/{tenant_id}/scheduling?policy=paused'.

Common situations: Typing the correct English 'decommissioned' instead of the code's 'decomissioned'; reusing pageserver or safekeeper vocabulary on the storage controller; clients written against an older controller release whose policy set differed; untrimmed values from configuration files.

Related errors


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