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
- Use exactly one of: active, activating, pause, decomissioned (single m)
- For decommissioning, mirror the literal in the error hint: 'decomissioned'
- Compare against the SkSchedulingPolicy FromStr impl in your checkout/release; the policy set changes between versions
- 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
- Expose the accepted policy strings as a const array next to your CLI/API and build choices from it
- Add shell completion / enum flags to CLIs so users pick policies interactively instead of typing them
- Pin a test that round-trips every enum variant through FromStr/Display after any policy-set change
- Beware the 'decomissioned' single-m spelling when porting scripts from docs
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
- invalid specifier '{first}'
- pageserver connection information should be provided
- safekeeper connstrings should be provided
- tenant id should be provided
- timeline id should be provided
AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16).
Data as JSON: /api/errors/175fecab1566b865.
Report an issue: GitHub.