diff --git a/resources/static/pages/verify_secondary_address.js b/resources/static/pages/verify_secondary_address.js
index 607a5621c80d4b477de7ea572c4008b007d6a30a..e94297adf8fce4786b99f8ebcbfd80ac0985efa6 100644
--- a/resources/static/pages/verify_secondary_address.js
+++ b/resources/static/pages/verify_secondary_address.js
@@ -15,6 +15,7 @@ BrowserID.verifySecondaryAddress = (function() {
       helpers = bid.Helpers,
       complete = helpers.complete,
       validation = bid.Validation,
+      tooltip = bid.Tooltip,
       token,
       sc,
       needsPassword,
@@ -49,7 +50,15 @@ BrowserID.verifySecondaryAddress = (function() {
 
         var selector = info.valid ? "#congrats" : "#cannotcomplete";
         pageHelpers.replaceFormWithNotice(selector, complete.curry(oncomplete, info.valid));
-      }, pageHelpers.getFailure(errors.verifyEmail, oncomplete));
+      }, function(info) {
+        if (info.network && info.network.status === 401) {
+          tooltip.showTooltip("#cannot_authenticate");
+          complete(oncomplete, false);
+        }
+        else {
+          pageHelpers.showFailure(errors.verifyEmail, info, oncomplete);
+        }
+      });
     }
     else {
       complete(oncomplete, false);
diff --git a/resources/static/test/cases/pages/verify_secondary_address.js b/resources/static/test/cases/pages/verify_secondary_address.js
index d7eacaa574bb8d489c7a5897d0913c2060d43a6b..23aea9f564ba7e0949ba0031eb7cc19540ff445d 100644
--- a/resources/static/test/cases/pages/verify_secondary_address.js
+++ b/resources/static/test/cases/pages/verify_secondary_address.js
@@ -125,6 +125,20 @@
     });
   });
 
+  asyncTest("password: bad password", function() {
+    $("#password").val("password");
+
+    xhr.useResult("mustAuth");
+    createController(config, function() {
+      xhr.useResult("badPassword");
+      controller.submit(function(status) {
+        equal(status, false, "correct status");
+        testHelpers.testTooltipVisible();
+        start();
+      });
+    });
+  });
+
   asyncTest("password: good password bad token", function() {
     $("#password").val("password");
 
diff --git a/resources/static/test/cases/shared/network.js b/resources/static/test/cases/shared/network.js
index e98a049029126e6eb623820d7a95fae563f7a7ea..ef310d932c20905bea77f4aca7dbe8e263c7ca85 100644
--- a/resources/static/test/cases/shared/network.js
+++ b/resources/static/test/cases/shared/network.js
@@ -174,9 +174,9 @@
     }, testHelpers.unexpectedXHRFailure);
   });
 
-  asyncTest("completeEmailRegistration with valid token, missing password", function() {
-    transport.useResult("missing_password");
-    network.completeEmailRegistration("token", undefined,
+  asyncTest("completeEmailRegistration with valid token, bad password", function() {
+    transport.useResult("badPassword");
+    network.completeEmailRegistration("token", "password",
       testHelpers.unexpectedSuccess,
       testHelpers.expectedXHRFailure);
   });
@@ -280,9 +280,9 @@
     }, testHelpers.unexpectedFailure);
   });
 
-  asyncTest("completeUserRegistration with valid token, missing password", function() {
-    transport.useResult("missing_password");
-    network.completeUserRegistration("token", undefined,
+  asyncTest("completeUserRegistration with valid token, bad password", function() {
+    transport.useResult("badPassword");
+    network.completeUserRegistration("token", "password",
       testHelpers.unexpectedSuccess,
       testHelpers.expectedXHRFailure);
   });
diff --git a/resources/static/test/mocks/xhr.js b/resources/static/test/mocks/xhr.js
index fc30baca72a584bef9a3ebc2470550ebdc073edf..e2d56028acabded23da7beaeea1bfa7726cfc26b 100644
--- a/resources/static/test/mocks/xhr.js
+++ b/resources/static/test/mocks/xhr.js
@@ -40,6 +40,7 @@ BrowserID.Mocks.xhr = (function() {
       "get /wsapi/email_for_token?token=token valid": { email: "testuser@testuser.com" },
       "get /wsapi/email_for_token?token=token mustAuth": { email: "testuser@testuser.com", must_auth: true },
       "get /wsapi/email_for_token?token=token needsPassword": { email: "testuser@testuser.com", needs_password: true },
+      "get /wsapi/email_for_token?token=token badPassword": { email: "testuser@testuser.com", must_auth: true },
       "get /wsapi/email_for_token?token=token invalid": { success: false },
       "post /wsapi/authenticate_user valid": { success: true, userid: 1 },
       "post /wsapi/authenticate_user invalid": { success: false },
@@ -53,7 +54,7 @@ BrowserID.Mocks.xhr = (function() {
       "post /wsapi/cert_key invalid": undefined,
       "post /wsapi/cert_key ajaxError": undefined,
       "post /wsapi/complete_email_addition valid": { success: true },
-      "post /wsapi/complete_email_addition missing_password": 401,
+      "post /wsapi/complete_email_addition badPassword": 401,
       "post /wsapi/complete_email_addition invalid": { success: false },
       "post /wsapi/complete_email_addition ajaxError": undefined,
       "post /wsapi/stage_user unknown_secondary": { success: true },
@@ -67,7 +68,7 @@ BrowserID.Mocks.xhr = (function() {
       "get /wsapi/user_creation_status?email=registered%40testuser.com noRegistration": { status: "noRegistration" },
       "get /wsapi/user_creation_status?email=registered%40testuser.com ajaxError": undefined,
       "post /wsapi/complete_user_creation valid": { success: true },
-      "post /wsapi/complete_user_creation missing_password": 401,
+      "post /wsapi/complete_user_creation badPassword": 401,
       "post /wsapi/complete_user_creation invalid": { success: false },
       "post /wsapi/complete_user_creation ajaxError": undefined,
       "post /wsapi/logout valid": { success: true },
diff --git a/resources/views/add_email_address.ejs b/resources/views/add_email_address.ejs
index 45b711cec7d8d7b53a9da83b7f2c1f933de87ca4..2bbff96c54e1f8f46cbc55b5125b11684b1c953b 100644
--- a/resources/views/add_email_address.ejs
+++ b/resources/views/add_email_address.ejs
@@ -30,6 +30,10 @@
                     <div class="tooltip" id="password_length" for="password">
                       <%= gettext('Password must be between 8 and 80 characters long.') %>
                     </div>
+
+                    <div id="cannot_authenticate" class="tooltip" for="password">
+                      <%= gettext('The account cannot be verified with this username and password.') %>
+                    </div>
                 </li>
 
                 <li class="password_entry" id="verify_password">
diff --git a/resources/views/verify_email_address.ejs b/resources/views/verify_email_address.ejs
index 1f275d3fe8c3362f98b6360c58484d401e2a9e9c..77f688b448d07e38570705fd6b9f3a25f17f2b17 100644
--- a/resources/views/verify_email_address.ejs
+++ b/resources/views/verify_email_address.ejs
@@ -30,6 +30,10 @@
                     <div class="tooltip" id="password_length" for="password">
                       <%= gettext('Password must be between 8 and 80 characters long.') %>
                     </div>
+
+                    <div id="cannot_authenticate" class="tooltip" for="password">
+                      <%= gettext('The account cannot be verified with this username and password.') %>
+                    </div>
                 </li>
 
                 <li class="password_entry" id="verify_password">