diff --git a/gui/gui.qrc b/gui/gui.qrc
index 112a1ce6b4c152abe84e6d01f882d3d5b0e6fc2a..36252dd6e29fc715bbb3b3d89324cedbf25bacb0 100644
--- a/gui/gui.qrc
+++ b/gui/gui.qrc
@@ -6,6 +6,7 @@
         <file>qml/DonateDialog.qml</file>
         <file>qml/LoginDialog.qml</file>
         <file>qml/LoginOKDialog.qml</file>
+        <file>qml/FailDialog.qml</file>
 
         <file>assets/icon/png/black/vpn_off.png</file>
         <file>assets/icon/png/black/vpn_on.png</file>
diff --git a/gui/providers/providers.json b/gui/providers/providers.json
index e0c52b87485a6befdd5a46ef259e192b6c3ea06d..8cbfbc0fe2250252194730fb2663d0635bae0555 100644
--- a/gui/providers/providers.json
+++ b/gui/providers/providers.json
@@ -18,4 +18,4 @@
             "timeStamp": "2020-09-08 03:42:39"
         }
     ]
-}
\ No newline at end of file
+}
diff --git a/gui/qml/FailDialog.qml b/gui/qml/FailDialog.qml
new file mode 100644
index 0000000000000000000000000000000000000000..3da421bfd3586ad40f164db9e0f524f6c13896d6
--- /dev/null
+++ b/gui/qml/FailDialog.qml
@@ -0,0 +1,23 @@
+import QtQuick 2.0
+import QtQuick.Dialogs 1.2
+
+MessageDialog {
+    title: qsTr("Initialization Error")
+    modality: Qt.NonModal
+    text: ""
+    onAccepted: retryOrQuit()
+    onRejected: retryOrQuit()
+
+    Component.onCompleted: {
+        buttons: MessageDialog.Ok
+    }
+
+    function retryOrQuit() {
+        if (ctx.loginDialog == 'true') {
+            login.visible = true
+        } else {
+            backend.quit()
+        }
+    }
+}
+
diff --git a/gui/qml/LoginDialog.qml b/gui/qml/LoginDialog.qml
index 897081b7c3a7ce2d9f0d23e7d6e40307800fd1fb..44a1d7936acb141b8bbf2f6914c55d3df77205ac 100644
--- a/gui/qml/LoginDialog.qml
+++ b/gui/qml/LoginDialog.qml
@@ -5,10 +5,15 @@ import QtQuick.Controls 1.4
 Dialog {
     standardButtons: StandardButton.Ok
     title: qsTr("Login")
+
     Column {
         anchors.fill: parent
         Text {
-            text: qsTr("Log in with your library credentials")
+            text: getLoginText()
+            font.bold: true
+        }
+        Text {
+            text: getDetailedText()
         }
         TextField {
             id: username
@@ -25,4 +30,16 @@ Dialog {
     visible: false
     onAccepted: backend.login(username.text, password.text)
     onRejected: backend.quit()
+
+    function getLoginText() {
+        if (allowEmptyPass) {
+            return qsTr("Enter your Patron ID")
+        } else {
+            return qsTr("Log in with your library credentials")
+        }
+    }
+
+    function getDetailedText() {
+        return qsTr("You can check your Patron ID number in the back of your library card")
+    }
 }
diff --git a/gui/qml/main.qml b/gui/qml/main.qml
index f03034525d8047817bb7ce8cfa37b816030d54d8..4d0e648c4f53e2d872d2e43dd6cbcbb23dc95813 100644
--- a/gui/qml/main.qml
+++ b/gui/qml/main.qml
@@ -37,16 +37,30 @@ ApplicationWindow {
                } else if ( ctx.errors == "nopolkit" ) {
                    showInitFailure(qsTr("Could not find polkit agent."))
                } else {
-                   //: %1 -> application name
-                   //: %2 -> error string
-                   showInitFailure(qsTr("Got an error starting %1: %2").arg(ctx.appName).arg(ctx.errors))
-                   console.debug(ctx.errors)
+                   showInitFailure()
                }
             }
         }
     }
 
     function showInitFailure(msg) {
+      console.debug("ERRORS:", ctx.errors)
+      if (msg == undefined) {
+          if (ctx.errors == 'bad_auth') {
+              if (allowEmptyPass) {
+                  // For now, this is a libraryVPN, so we can be explicit about what credentials are here.
+                  // Another option to consider is to customize the error strings while vendoring.
+                  msg = qsTr("Please check your Patron ID")
+              } else {
+                  msg = qsTr("Could not log in with those credentials, please retry")
+              }
+              initFailure.title = qsTr("Login Error")
+          } else {
+              //: %1 -> application name
+              //: %2 -> error string
+              msg = qsTr("Got an error starting %1: %2").arg(ctx.appName).arg(ctx.errors)
+          }
+      }
       initFailure.text = msg
       initFailure.visible  = true
     }
@@ -249,6 +263,7 @@ ApplicationWindow {
         id: about
         visible: false
     }
+   
 
     LoginDialog {
         id: login
@@ -279,22 +294,8 @@ ApplicationWindow {
         visible: false
     }
 
-    MessageDialog {
+    FailDialog {
         id: initFailure
-        buttons: MessageDialog.Ok
-        modality: Qt.NonModal
-        title: qsTr("Initialization Error")
-        text: ""
         visible: false
-    	onAccepted: retryOrQuit()
-        onRejected: retryOrQuit()
-        
-        function retryOrQuit() {
-            if (ctx.loginDialog == 'true') {
-                login.visible = true
-            } else {
-                backend.quit()
-            }
-        }
     }
 }