neondatabase/neon · error
This command is not a clean node decommission, and uncleanly
Error message
This command is not a clean node decommission, and uncleanly drops all controller state for the node, without checking if any tenants still refer to it. If you know what you're doing, add `--unclean` to proceed.
What it means
storcon_cli's node-drop command POSTs debug/v1/node/{node_id}/drop and removes all controller state for the node without checking whether tenants still refer to it — it is not a clean decommission. The --unclean flag is a mandatory confirmation; without it the command bails before making any request.
Source
Thrown at control_plane/storcon_cli/src/main.rs:953
.await?;
}
Command::TenantDrop { tenant_id, unclean } => {
if !unclean {
anyhow::bail!(
"This command is not a tenant deletion, and uncleanly drops all controller state for the tenant. If you know what you're doing, add `--unclean` to proceed."
)
}
storcon_client
.dispatch::<(), ()>(
Method::POST,
format!("debug/v1/tenant/{tenant_id}/drop"),
None,
)
.await?;
}
Command::NodeDrop { node_id, unclean } => {
if !unclean {
anyhow::bail!(
"This command is not a clean node decommission, and uncleanly drops all controller state for the node, without checking if any tenants still refer to it. If you know what you're doing, add `--unclean` to proceed."
)
}
storcon_client
.dispatch::<(), ()>(Method::POST, format!("debug/v1/node/{node_id}/drop"), None)
.await?;
}
Command::NodeDelete { node_id } => {
eprintln!("Warning: This command is obsolete and will be removed in a future version");
eprintln!("Use `NodeStartDelete` instead, if possible");
storcon_client
.dispatch::<(), ()>(Method::DELETE, format!("control/v1/node/{node_id}"), None)
.await?;
}
Command::NodeStartDelete { node_id, force } => {
let query = if force {
format!("control/v1/node/{node_id}/delete?force=true")
} else {View on GitHub (pinned to 8f60b04da4)
Solutions
- Use the clean decommission path instead: storcon_cli node start-delete / NodeStartDelete, which drains the node safely
- If you accept the risk of dangling controller state, re-run node-drop with --unclean
- After an unclean drop, expect to repair tenant placement for shards that referenced the dropped node
Example fix
# before storcon_cli node-drop --node-id <id> # after (only if unclean drop is intended) storcon_cli node-drop --node-id <id> --unclean
Defensive patterns
Strategy: validation
Prevention
- Default decommissioning automation to node start-delete; treat node-drop --unclean as a break-glass path
- Before an unclean node drop, list tenants on the node so you know what placement you will break
- Rebalance tenants off the node first whenever possible
When it happens
Trigger: Running storcon_cli node-drop without --unclean. The guard triggers purely on the missing flag, regardless of whether tenants reference the node.
Common situations: Operators using node-drop where NodeStartDelete (the clean, modern decommission path) is intended; automation written against the debug endpoint; decommissioning a node that still hosts attached shards and breaking tenant placement.
Related errors
- This command is not a tenant deletion, and uncleanly drops a
- Unknown scheduling policy '{s}', try active,essential,pause,
- Unknown availability state '{s}'
- Migration to {node} rejected, may require `--force` ({})
- AZ {} not found on any node: known AZs are: {:?}
AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16).
Data as JSON: /api/errors/674cb73e42e29af3.
Report an issue: GitHub.