dani-garcia/vaultwarden · critical
Error loading ciphers
Error message
Error loading ciphers
What it means
find_by_user loads the user's visible ciphers via Diesel .load::<Self> and unwraps with .expect("Error loading ciphers"). Any database failure during this query panics with this message: connection loss, schema mismatch, or deserialization errors.
Solutions
- Run pending migrations (automatic on startup; check DB schema version table)
- Verify DB connectivity and that the ciphers table exists with expected columns
- Check server logs for the underlying Diesel error printed before the panic
- Restore schema consistency from backup or re-run migrations after schema drift
Defensive patterns
Strategy: try-catch
Validate before calling
// before calling find_by_user, confirm schema is current: // run `vaultwarden` once and verify 'Migrations completed' in logs, // or check the __diesel_schema_migrations table has the latest version.
Try / catch
match ciphers::find_by_user(&user_uuid, &conn).await {
Ok(list) => list,
Err(e) => { error!("Cipher load failed: {e}"); return api_err(500); }
} Prevention
- Always let Vaultwarden run its migrations on startup
- Monitor DB connectivity and pool health
- Avoid manual schema edits; track diesel schema.rs in upgrades
- Verify schema after restore-from-backup operations
When it happens
Trigger: DB connection dropped mid-query, migrations not applied so the ciphers table/columns are missing, or a row whose column types/NULLs don't match the Cipher model fields.
Common situations: Upgrading Vaultwarden without running migrations (old schema); Postgres/MySQL restarted or pooled connections expired; manually edited schema diverging from diesel models.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- Error loading collections
- Error loading devices
- Error loading emergency_access
- Error loading push devices
- Error loading users_collections
AI-assisted analysis of dani-garcia/vaultwarden@cc67d644f6 (2026-09-19).
Data as JSON: /api/errors/dcb815b0b19e470a.
Report an issue: GitHub.
Appendix: source
Thrown at src/db/models/cipher.rs:850
.filter(ciphers::user_uuid.eq(user_uuid)) // Cipher owner
.or_filter(users_organizations::access_all.eq(true)) // access_all in org
.or_filter(users_collections::user_uuid.eq(user_uuid)) // Access to collection
.or_filter(groups::access_all.eq(true)) // Access via groups
.or_filter(collections_groups::collections_uuid.is_not_null()) // Access via groups
.into_boxed();
if !visible_only {
query = query.or_filter(
users_organizations::atype.le(MembershipType::Admin as i32), // Org admin/owner
);
}
// Only filter for one specific cipher
if !cipher_uuids.is_empty() {
query = query.filter(ciphers::uuid.eq_any(cipher_uuids));
}
query.select(ciphers::all_columns).distinct().load::<Self>(conn).expect("Error loading ciphers")
})
.await
} else {
conn.run(move |conn| {
let mut query = ciphers::table
.left_join(ciphers_collections::table.on(ciphers::uuid.eq(ciphers_collections::cipher_uuid)))
.left_join(
users_organizations::table.on(ciphers::organization_uuid
.eq(users_organizations::org_uuid.nullable())
.and(users_organizations::user_uuid.eq(user_uuid))
.and(users_organizations::status.eq(MembershipStatus::Confirmed as i32))),
)
.left_join(
users_collections::table.on(ciphers_collections::collection_uuid
.eq(users_collections::collection_uuid)
// Ensure that users_collections::user_uuid is NULL for unconfirmed users.
.and(users_organizations::user_uuid.eq(users_collections::user_uuid))),
)View on GitHub (pinned to cc67d644f6)