dani-garcia/vaultwarden · error
Error on sending email
Error message
Error on sending email
What it means
After the timeout job approves a recovery and mail is enabled, mail::send_emergency_access_recovery_timed_out(...).expect("Error on sending email") panics the job task on any SMTP failure (connection refused, auth rejected, TLS problem). The DB status update has already committed, so a later rerun will not re-send this notification — the mail is lost even after SMTP is fixed.
Source
Thrown at src/api/core/emergency_access.rs:764
if CONFIG.mail_enabled() {
// get grantor user to send Accepted email
let grantor_user =
User::find_by_uuid(&emer.grantor_uuid, &conn).await.expect("Grantor user not found");
// get grantee user to send Accepted email
let grantee_user =
User::find_by_uuid(&emer.grantee_uuid.clone().expect("Grantee user invalid"), &conn)
.await
.expect("Grantee user not found");
mail::send_emergency_access_recovery_timed_out(
&grantor_user.email,
&grantee_user.name,
emer.get_type_as_str(),
)
.await
.expect("Error on sending email");
mail::send_emergency_access_recovery_approved(&grantee_user.email, &grantor_user.name)
.await
.expect("Error on sending email");
}
}
}
} else {
error!("Failed to get DB connection while searching emergency request timed out");
}
}
pub async fn emergency_notification_reminder_job(pool: DbPool) {
debug!("Start emergency_notification_reminder_job");
if !CONFIG.emergency_access_allowed() {
return;
}
View on GitHub (pinned to 0cefa4cca7)
Solutions
- Fix SMTP config (SMTP_HOST, SMTP_PORT, SMTP_SECURITY, SMTP_USERNAME/SMTP_PASSWORD) and verify with the 'Test SMTP' button on /admin/diagnostics
- Restart Vaultwarden to respawn the panicked job task
- Accept that this particular notification was lost; inform the affected user manually if needed
- Code fix: log mail failures instead of expect
Example fix
// before
mail::send_emergency_access_recovery_timed_out(&grantor_user.email, &grantee_user.name, emer.get_type_as_str())
.await
.expect("Error on sending email");
// after
if let Err(e) = mail::send_emergency_access_recovery_timed_out(&grantor_user.email, &grantee_user.name, emer.get_type_as_str()).await {
error!("Failed to send recovery timed out mail for {}: {e}", emer.uuid);
} Defensive patterns
Strategy: try-catch
Validate before calling
# Probe SMTP reachability with the same host/port/security Vaultwarden uses
openssl s_client -connect ${SMTP_HOST}:${SMTP_PORT} -starttls smtp < /dev/null
# for implicit TLS (SMTP_SECURITY=starttls vs secure) use without -starttls:
# openssl s_client -connect ${SMTP_HOST}:${SMTP_PORT} < /dev/null Try / catch
// Mail failures in jobs: log and continue, never panic
let mail_res = mail::send_emergency_access_recovery_timed_out(&grantor_user.email, &grantee_user.name, emer.get_type_as_str()).await;
if let Err(e) = mail_res {
error!("emergency timeout job: mail send failed for {}: {e}", emer.uuid);
} Prevention
- Run 'Test SMTP' from /admin/diagnostics after any mail config change
- Keep SMTP credentials current and monitor provider expiry
- Treat job panics as alerts: one dead task stops future runs until restart
When it happens
Trigger: EMERGENCY_REQUEST_TIMEOUT job firing while SMTP is misconfigured or unreachable: wrong SMTP_HOST/PORT/SECURITY, expired credentials, DNS or firewall issues.
Common situations: SMTP provider credentials rotated; mail settings changed but untested; SMTP enabled after recoveries had already started; provider outages.
Related errors
- Grantee user should exist but does not!
- Grantee email does not exists
- Unable to update emergency access status
- Grantor user not found
- Grantee user invalid
AI-assisted analysis of dani-garcia/vaultwarden@0cefa4cca7 (2026-08-16).
Data as JSON: /api/errors/36cd5fdcbf472dee.
Report an issue: GitHub.