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

  1. Fix SMTP config (SMTP_HOST, SMTP_PORT, SMTP_SECURITY, SMTP_USERNAME/SMTP_PASSWORD) and verify with the 'Test SMTP' button on /admin/diagnostics
  2. Restart Vaultwarden to respawn the panicked job task
  3. Accept that this particular notification was lost; inform the affected user manually if needed
  4. 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

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


AI-assisted analysis of dani-garcia/vaultwarden@0cefa4cca7 (2026-08-16). Data as JSON: /api/errors/36cd5fdcbf472dee. Report an issue: GitHub.