sigoden/dufs · error · anyhow::Error

Not found user

Error message

Not found user '{user}'

What it means

`generate_token` looks up the requested user in the configured `users` map to obtain the password used to derive the signing key. If the user was never configured (no `user:pass@paths` entry in Auth::new), token generation fails with 'Not found user'. The user name is echoed in the message.

Solutions

  1. Use a username exactly as configured in the `--auth user:pass@paths` entries.
  2. List/verify configured users before generating tokens.
  3. Fix any case or whitespace differences in the user name.
  4. If anonymous access is needed, use the anonymous paths mechanism rather than generate_token.

Example fix

// before
let token = auth.generate_token("/", "Alice")?; // configured as alice
// after
let token = auth.generate_token("/", "alice")?;
Defensive patterns

Strategy: validation

Validate before calling

fn user_configured(users: &[String], user: &str) -> bool { users.iter().any(|u| u == user) }
assert!(user_configured(&configured_users, "alice"), "user not in --auth config");

Prevention

When it happens

Trigger: Calling `auth.generate_token(path, user)` with a user name absent from the server's auth configuration, including case/whitespace mismatches.

Common situations: Typo in the username when minting download/share links; renaming a user in `--auth` but stale code/URLs still referencing the old name; requesting tokens for anonymous access which is not a user.

Understand the failure class

Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.

Related errors


AI-assisted analysis of sigoden/dufs@fe7fd564f8 (2026-09-09). Data as JSON: /api/errors/0bab216b1d11dff5. Report an issue: GitHub.

Appendix: source

Thrown at src/auth.rs:166

            return (None, None);
        }

        if !guard_options && method == Method::OPTIONS {
            return (None, Some(AccessPaths::new(AccessPerm::ReadOnly)));
        }

        if let Some(ap) = self.anonymous.as_ref() {
            return (None, ap.guard(path, method));
        }

        (None, None)
    }

    pub fn generate_token(&self, path: &str, user: &str) -> Result<String> {
        let (pass, _) = self
            .users
            .get(user)
            .ok_or_else(|| anyhow!("Not found user '{user}'"))?;
        let exp = unix_now().as_millis() as u64 + TOKEN_EXPIRATION;
        let message = format!("{path}:{exp}");
        let mut signing_key = derive_secret_key(user, pass);
        let sig = signing_key.sign(message.as_bytes()).to_bytes();

        let mut raw = Vec::with_capacity(64 + 8 + user.len());
        raw.extend_from_slice(&sig);
        raw.extend_from_slice(&exp.to_be_bytes());
        raw.extend_from_slice(user.as_bytes());

        Ok(hex::encode(raw))
    }

    fn verify_token<'a>(&'a self, token: &str, path: &str) -> Result<(String, &'a AccessPaths)> {
        let raw = hex::decode(token)?;

        if raw.len() < 72 {
            bail!("Invalid token");

View on GitHub (pinned to fe7fd564f8)