stalwartlabs/stalwart · error · ScimError

Not Found

Error message

Not Found

What it means

This is a SCIM protocol Error carrying HTTP status 404 ("Not Found"), built by the `Error::not_found()` constructor in crates/scim-proto. The library throws it to signal that the addressed SCIM resource (a User, Group, or Enterprise extension endpoint) does not exist on the server. It contains no detail message, only the status code and default reason phrase.

Source

Thrown at crates/scim-proto/src/message/error.rs:171

    pub fn uniqueness(detail: impl Into<Cow<'static, str>>) -> Self {
        Error {
            status: 409,
            scim_type: Some(ScimType::Uniqueness),
            detail: Some(detail.into()),
        }
    }

    pub fn unauthorized() -> Self {
        Error::new(401)
    }

    pub fn forbidden(detail: impl Into<Cow<'static, str>>) -> Self {
        Error::new(403).with_detail(detail)
    }

    pub fn not_found() -> Self {
        Error::new(404)
    }

    pub fn conflict(detail: impl Into<Cow<'static, str>>) -> Self {
        Error::new(409).with_detail(detail)
    }

    pub fn precondition_failed() -> Self {
        Error::new(412)
    }

    pub fn max_operations_exceeded(max_operations: usize) -> Self {
        Error::new(413).with_detail(format!(
            "The number of operations in the bulk request exceeds the maxOperations ({max_operations})."
        ))
    }

    pub fn max_payload_size_exceeded(max_payload_size: usize) -> Self {
        Error::new(413).with_detail(format!(

View on GitHub (pinned to e962003857)

Solutions

  1. List or query the resource collection first (e.g. GET /Users?filter=userName eq "...") to obtain a valid, currently-existing ID.
  2. Verify the resource was not deleted and that you are targeting the correct tenant/base URL.
  3. Check the ID format and that it matches exactly what the server returned earlier (no truncation or case change).

Example fix

// before
let user = client.get_user("stale-id").await?;
// after
if let Some(user) = client.find_user_by_username("jdoe@example.com").await? {
    // proceed with user.id
}
Defensive patterns

Strategy: validation

Validate before calling

// resolve the ID first and only use IDs returned by the server
let found = client.query_users(format!("userName eq \"{username}\"")).await?;
if found.resources.is_empty() { return Err(anyhow!("user does not exist")); }
let id = found.resources[0].id.clone();

Prevention

When it happens

Trigger: Calling any scim-proto error path that invokes `Error::not_found()`, i.e. handling GET/PUT/PATCH/DELETE on a resource ID that the server cannot resolve. In a server implementation this is returned when a lookup by ID yields no record.

Common situations: A client dereferences a stale user ID after the account was deleted; an ID is copied from a different tenant/environment; a typo or wrong-case ID is used in the URL path (e.g. /Users/abc123 with a wrong suffix).

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of stalwartlabs/stalwart@e962003857 (2026-09-06). Data as JSON: /api/errors/594f1f37534af190. Report an issue: GitHub.