rustfs/rustfs · error · policy::Error
'Resource' and 'NotResource' cannot both be specified in the
Error message
'Resource' and 'NotResource' cannot both be specified in the same statement
What it means
Returned by Statement::is_valid (crates/policy/src/policy/statement.rs:343) when a statement lists both a non-empty Resource and a non-empty NotResource. Like Action/NotAction, the positive and negated resource selectors are mutually exclusive; a statement containing both is rejected at parse time.
Source
Thrown at crates/policy/src/policy.rs:58
#[derive(thiserror::Error, Debug)]
#[cfg_attr(test, derive(Eq, PartialEq))]
pub enum Error {
#[error("invalid Version '{0}'")]
InvalidVersion(String),
#[error("invalid Effect '{0}'")]
InvalidEffect(String),
#[error("both 'Action' and 'NotAction' are empty")]
NonAction,
#[error("'Action' and 'NotAction' cannot both be specified in the same statement")]
BothActionAndNotAction,
#[error("'Resource' is empty")]
NonResource,
#[error("'Resource' and 'NotResource' cannot both be specified in the same statement")]
BothResourceAndNotResource,
#[error("invalid key name: '{0}'")]
InvalidKeyName(String),
#[error("invalid key: '{0}'")]
InvalidKey(String),
#[error("invalid action: '{0}'")]
InvalidAction(String),
#[error("'Action' contains mixed action families in the same statement")]
MixedActionFamilies,
#[error("invalid resource, type: '{0}', pattern: '{1}'")]
InvalidResource(String, String),
#[error("KMS resources require a statement whose actions are all KMS actions")]View on GitHub (pinned to 35af688cd9)
Solutions
- Delete one of the two keys so each statement has exactly one resource selection mode
- Split into two statements if both scopes genuinely need different effects
- Automate a pre-flight check that flags statements containing both keys
Example fix
// before
{ "Effect": "Deny",
"Action": "s3:*",
"Resource": "arn:aws:s3:::secret/*",
"NotResource": "arn:aws:s3:::public/*" }
// after
{ "Effect": "Deny",
"Action": "s3:*",
"Resource": "arn:aws:s3:::secret/*" } Defensive patterns
Strategy: validation
Validate before calling
fn not_both_resource_modes(stmt: &serde_json::Value) -> bool {
let has = |k: &str| stmt.get(k).map(|v| !v.is_null()).unwrap_or(false);
!(has("Resource") && has("NotResource"))
} Try / catch
match statement.is_valid() {
Err(Error::PolicyError(IamError::BothResourceAndNotResource)) => { /* keep one mode */ }
Ok(()) => { /* ok */ }
Err(e) => return Err(e),
} Prevention
- When adding NotResource exclusions, delete the original Resource key in the same edit
- Lint merged policies for dual resource modes
When it happens
Trigger: A policy statement JSON containing both "Resource" and "NotResource" keys with non-empty values in any policy upload path.
Common situations: Incremental policy editing where a NotResource was added to exclude a new bucket but the original Resource list was left in place; merging policies with a naive union of fields.
Related errors
- both 'Action' and 'NotAction' are empty
- 'Action' and 'NotAction' cannot both be specified in the sam
- 'Resource' is empty
- 'Action' contains mixed action families in the same statemen
- {0}
AI-assisted analysis of rustfs/rustfs@35af688cd9 (2026-08-20).
Data as JSON: /api/errors/46579440742231a7.
Report an issue: GitHub.