diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -4001,6 +4001,7 @@
     'PhabricatorPeopleDeleteController' => 'applications/people/controller/PhabricatorPeopleDeleteController.php',
     'PhabricatorPeopleDetailsProfileMenuItem' => 'applications/people/menuitem/PhabricatorPeopleDetailsProfileMenuItem.php',
     'PhabricatorPeopleDisableController' => 'applications/people/controller/PhabricatorPeopleDisableController.php',
+    'PhabricatorPeopleEmailLoginMailEngine' => 'applications/people/mail/PhabricatorPeopleEmailLoginMailEngine.php',
     'PhabricatorPeopleEmpowerController' => 'applications/people/controller/PhabricatorPeopleEmpowerController.php',
     'PhabricatorPeopleExternalPHIDType' => 'applications/people/phid/PhabricatorPeopleExternalPHIDType.php',
     'PhabricatorPeopleIconSet' => 'applications/people/icon/PhabricatorPeopleIconSet.php',
@@ -10231,6 +10232,7 @@
     'PhabricatorPeopleDeleteController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleDetailsProfileMenuItem' => 'PhabricatorProfileMenuItem',
     'PhabricatorPeopleDisableController' => 'PhabricatorPeopleController',
+    'PhabricatorPeopleEmailLoginMailEngine' => 'PhabricatorPeopleMailEngine',
     'PhabricatorPeopleEmpowerController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleExternalPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorPeopleIconSet' => 'PhabricatorIconSet',
diff --git a/src/applications/auth/controller/PhabricatorEmailLoginController.php b/src/applications/auth/controller/PhabricatorEmailLoginController.php
--- a/src/applications/auth/controller/PhabricatorEmailLoginController.php
+++ b/src/applications/auth/controller/PhabricatorEmailLoginController.php
@@ -94,29 +94,34 @@
         }
 
         if (!$errors) {
-          $body = $this->newAccountLoginMailBody(
-            $target_user,
-            $is_logged_in);
+          $target_address = new PhutilEmailAddress($target_email->getAddress());
+
+          $mail_engine = id(new PhabricatorPeopleEmailLoginMailEngine())
+            ->setSender($viewer)
+            ->setRecipient($target_user)
+            ->setRecipientAddress($target_address);
+
+          try {
+            $mail_engine->validateMail();
+          } catch (PhabricatorPeopleMailEngineException $ex) {
+            return $this->newDialog()
+              ->setTitle($ex->getTitle())
+              ->appendParagraph($ex->getBody())
+              ->addCancelButton('/auth/start/', pht('Done'));
+          }
+
+          $mail_engine->sendMail();
 
           if ($is_logged_in) {
-            $subject = pht('[Phabricator] Account Password Link');
             $instructions = pht(
               'An email has been sent containing a link you can use to set '.
               'a password for your account.');
           } else {
-            $subject = pht('[Phabricator] Account Login Link');
             $instructions = pht(
               'An email has been sent containing a link you can use to log '.
               'in to your account.');
           }
 
-          $mail = id(new PhabricatorMetaMTAMail())
-            ->setSubject($subject)
-            ->setForceDelivery(true)
-            ->addRawTos(array($target_email->getAddress()))
-            ->setBody($body)
-            ->saveAndSend();
-
           return $this->newDialog()
             ->setTitle(pht('Check Your Email'))
             ->setShortTitle(pht('Email Sent'))
@@ -182,55 +187,6 @@
       ->addSubmitButton(pht('Send Email'));
   }
 
-  private function newAccountLoginMailBody(
-    PhabricatorUser $user,
-    $is_logged_in) {
-
-    $engine = new PhabricatorAuthSessionEngine();
-    $uri = $engine->getOneTimeLoginURI(
-      $user,
-      null,
-      PhabricatorAuthSessionEngine::ONETIME_RESET);
-
-    $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
-    $have_passwords = $this->isPasswordAuthEnabled();
-
-    if ($have_passwords) {
-      if ($is_logged_in) {
-        $body = pht(
-          'You can use this link to set a password on your account:'.
-          "\n\n  %s\n",
-          $uri);
-      } else if ($is_serious) {
-        $body = pht(
-          "You can use this link to reset your Phabricator password:".
-          "\n\n  %s\n",
-          $uri);
-      } else {
-        $body = pht(
-          "Condolences on forgetting your password. You can use this ".
-          "link to reset it:\n\n".
-          "  %s\n\n".
-          "After you set a new password, consider writing it down on a ".
-          "sticky note and attaching it to your monitor so you don't ".
-          "forget again! Choosing a very short, easy-to-remember password ".
-          "like \"cat\" or \"1234\" might also help.\n\n".
-          "Best Wishes,\nPhabricator\n",
-          $uri);
-
-      }
-    } else {
-      $body = pht(
-        "You can use this login link to regain access to your Phabricator ".
-        "account:".
-        "\n\n".
-        "  %s\n",
-        $uri);
-    }
-
-    return $body;
-  }
-
   private function isPasswordAuthEnabled() {
     return (bool)PhabricatorPasswordAuthProvider::getPasswordProvider();
   }
diff --git a/src/applications/people/mail/PhabricatorPeopleEmailLoginMailEngine.php b/src/applications/people/mail/PhabricatorPeopleEmailLoginMailEngine.php
new file mode 100644
--- /dev/null
+++ b/src/applications/people/mail/PhabricatorPeopleEmailLoginMailEngine.php
@@ -0,0 +1,107 @@
+<?php
+
+final class PhabricatorPeopleEmailLoginMailEngine
+  extends PhabricatorPeopleMailEngine {
+
+  public function validateMail() {
+    $recipient = $this->getRecipient();
+
+    if ($recipient->getIsDisabled()) {
+      $this->throwValidationException(
+        pht('User is Disabled'),
+        pht(
+          'You can not send an email login link to this email address '.
+          'because the associated user account is disabled.'));
+    }
+
+    if (!$recipient->canEstablishWebSessions()) {
+      $this->throwValidationException(
+        pht('Not a Normal User'),
+        pht(
+          'You can not send an email login link to this email address '.
+          'because the associated user account is not a normal user account '.
+          'and can not log in to the web interface.'));
+    }
+  }
+
+  protected function newMail() {
+    $is_set_password = $this->isSetPasswordWorkflow();
+
+    if ($is_set_password) {
+      $subject = pht('[Phabricator] Account Password Link');
+    } else {
+      $subject = pht('[Phabricator] Account Login Link');
+    }
+
+    $recipient = $this->getRecipient();
+    $engine = new PhabricatorAuthSessionEngine();
+    $login_uri = $engine->getOneTimeLoginURI(
+      $recipient,
+      null,
+      PhabricatorAuthSessionEngine::ONETIME_RESET);
+
+    $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
+    $have_passwords = $this->isPasswordAuthEnabled();
+
+    if ($have_passwords) {
+      if ($is_set_password) {
+        $body = pht(
+          'You can use this link to set a password on your account:'.
+          "\n\n  %s\n",
+          $login_uri);
+      } else if ($is_serious) {
+        $body = pht(
+          "You can use this link to reset your Phabricator password:".
+          "\n\n  %s\n",
+          $login_uri);
+      } else {
+        $body = pht(
+          "Condolences on forgetting your password. You can use this ".
+          "link to reset it:\n\n".
+          "  %s\n\n".
+          "After you set a new password, consider writing it down on a ".
+          "sticky note and attaching it to your monitor so you don't ".
+          "forget again! Choosing a very short, easy-to-remember password ".
+          "like \"cat\" or \"1234\" might also help.\n\n".
+          "Best Wishes,\nPhabricator\n",
+          $login_uri);
+
+      }
+    } else {
+      $body = pht(
+        "You can use this login link to regain access to your Phabricator ".
+        "account:".
+        "\n\n".
+        "  %s\n",
+        $login_uri);
+    }
+
+    return id(new PhabricatorMetaMTAMail())
+      ->setSubject($subject)
+      ->setBody($body);
+  }
+
+  private function isPasswordAuthEnabled() {
+    return (bool)PhabricatorPasswordAuthProvider::getPasswordProvider();
+  }
+
+  private function isSetPasswordWorkflow() {
+    $sender = $this->getSender();
+    $recipient = $this->getRecipient();
+
+    // Users can hit the "login with an email link" workflow while trying to
+    // set a password on an account which does not yet have a password. We
+    // require they verify that they own the email address and send them
+    // through the email  login flow. In this case, the messaging is slightly
+    // different.
+
+    if ($sender->getPHID()) {
+      if ($sender->getPHID() === $recipient->getPHID()) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+}
diff --git a/src/applications/people/mail/PhabricatorPeopleMailEngine.php b/src/applications/people/mail/PhabricatorPeopleMailEngine.php
--- a/src/applications/people/mail/PhabricatorPeopleMailEngine.php
+++ b/src/applications/people/mail/PhabricatorPeopleMailEngine.php
@@ -5,6 +5,7 @@
 
   private $sender;
   private $recipient;
+  private $recipientAddress;
 
   final public function setSender(PhabricatorUser $sender) {
     $this->sender = $sender;
@@ -30,6 +31,22 @@
     return $this->recipient;
   }
 
+  final public function setRecipientAddress(PhutilEmailAddress $address) {
+    $this->recipientAddress = $address;
+    return $this;
+  }
+
+  final public function getRecipientAddress() {
+    if (!$this->recipientAddress) {
+      throw new PhutilInvalidStateException('recipientAddress');
+    }
+    return $this->recipientAddress;
+  }
+
+  final public function hasRecipientAddress() {
+    return ($this->recipientAddress !== null);
+  }
+
   final public function canSendMail() {
     try {
       $this->validateMail();
@@ -43,6 +60,14 @@
     $this->validateMail();
     $mail = $this->newMail();
 
+    if ($this->hasRecipientAddress()) {
+      $recipient_address = $this->getRecipientAddress();
+      $mail->addRawTos(array($recipient_address->getAddress()));
+    } else {
+      $recipient = $this->getRecipient();
+      $mail->addTos(array($recipient->getPHID()));
+    }
+
     $mail
       ->setForceDelivery(true)
       ->save();
@@ -53,7 +78,6 @@
   abstract public function validateMail();
   abstract protected function newMail();
 
-
   final protected function throwValidationException($title, $body) {
     throw new PhabricatorPeopleMailEngineException($title, $body);
   }
diff --git a/src/applications/people/mail/PhabricatorPeopleUsernameMailEngine.php b/src/applications/people/mail/PhabricatorPeopleUsernameMailEngine.php
--- a/src/applications/people/mail/PhabricatorPeopleUsernameMailEngine.php
+++ b/src/applications/people/mail/PhabricatorPeopleUsernameMailEngine.php
@@ -30,7 +30,6 @@
 
   protected function newMail() {
     $sender = $this->getSender();
-    $recipient = $this->getRecipient();
 
     $sender_username = $sender->getUsername();
     $sender_realname = $sender->getRealName();
@@ -52,7 +51,6 @@
         $new_username));
 
     return id(new PhabricatorMetaMTAMail())
-      ->addTos(array($recipient->getPHID()))
       ->setSubject(pht('[Phabricator] Username Changed'))
       ->setBody($body);
   }
diff --git a/src/applications/people/mail/PhabricatorPeopleWelcomeMailEngine.php b/src/applications/people/mail/PhabricatorPeopleWelcomeMailEngine.php
--- a/src/applications/people/mail/PhabricatorPeopleWelcomeMailEngine.php
+++ b/src/applications/people/mail/PhabricatorPeopleWelcomeMailEngine.php
@@ -104,7 +104,6 @@
     $message = implode("\n\n", $message);
 
     return id(new PhabricatorMetaMTAMail())
-      ->addTos(array($recipient->getPHID()))
       ->setSubject(pht('[Phabricator] Welcome to Phabricator'))
       ->setBody($message);
   }