diff --git a/Core/FormBrowser.cs b/Core/FormBrowser.cs
index 7fdd6557..061e28b6 100644
--- a/Core/FormBrowser.cs
+++ b/Core/FormBrowser.cs
@@ -79,6 +79,8 @@ public FormBrowser(PluginManager pluginManager, UpdaterSettings updaterSettings)
 
             this.browser.LoadingStateChanged += browser_LoadingStateChanged;
             this.browser.FrameLoadEnd += browser_FrameLoadEnd;
+            this.browser.LoadError += browser_LoadError;
+            this.browser.AddressChanged += browser_AddressChanged;
             this.browser.RegisterAsyncJsObject("$TD", new TweetDeckBridge(this, notification));
             this.browser.RegisterAsyncJsObject("$TDP", plugins.Bridge);
 
@@ -163,6 +165,25 @@ private void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
             }
         }
 
+        private void browser_LoadError(object sender, LoadErrorEventArgs e){
+            if (!e.FailedUrl.StartsWith("http://td/") && !e.FailedUrl.StartsWith("td:")){
+                string errorPage = ScriptLoader.LoadResource("pages/error.html", true);
+
+                if (errorPage != null){
+                    browser.LoadHtml(errorPage.Replace("{err}", BrowserUtils.GetErrorName(e.ErrorCode)), "http://td/error");
+                }
+            }
+        }
+
+        private void browser_AddressChanged(object sender, AddressChangedEventArgs e){
+            if (e.Address.StartsWith("td:")){
+                switch(e.Address){
+                    case "td:reload": ReloadToTweetDeck(); break;
+                    case "td:exit": this.InvokeAsyncSafe(ForceClose); break;
+                }
+            }
+        }
+
         private void FormBrowser_Activated(object sender, EventArgs e){
             if (!isLoaded)return;
 
diff --git a/Core/Utils/BrowserUtils.cs b/Core/Utils/BrowserUtils.cs
index 23bfd81b..9d3023e9 100644
--- a/Core/Utils/BrowserUtils.cs
+++ b/Core/Utils/BrowserUtils.cs
@@ -67,6 +67,10 @@ public static string ConvertPascalCaseToScreamingSnakeCase(string str){
             return Regex.Replace(str, @"(\p{Ll})(\P{Ll})|(\P{Ll})(\P{Ll}\p{Ll})", "$1$3_$2$4").ToUpperInvariant();
         }
 
+        public static string GetErrorName(CefErrorCode code){
+            return ConvertPascalCaseToScreamingSnakeCase(Enum.GetName(typeof(CefErrorCode), code) ?? string.Empty);
+        }
+
         public static void DownloadFileAsync(string url, string target, Action<Exception> onFailure){
             WebClient client = new WebClient{ Proxy = null };
             client.Headers[HttpRequestHeader.UserAgent] = HeaderUserAgent;
diff --git a/Resources/ScriptLoader.cs b/Resources/ScriptLoader.cs
index 0cc749b8..6718460f 100644
--- a/Resources/ScriptLoader.cs
+++ b/Resources/ScriptLoader.cs
@@ -9,11 +9,14 @@ namespace TweetDck.Resources{
     static class ScriptLoader{
         private const string UrlPrefix = "td:";
 
-        public static string LoadResource(string name){
+        public static string LoadResource(string name, bool silent = false){
             try{
                 return File.ReadAllText(Path.Combine(Program.ScriptPath, name), Encoding.UTF8);
             }catch(Exception ex){
-                MessageBox.Show("Unfortunately, "+Program.BrandName+" could not load the "+name+" file. The program will continue running with limited functionality.\r\n\r\n"+ex.Message, Program.BrandName+" Has Failed :(", MessageBoxButtons.OK, MessageBoxIcon.Error);
+                if (!silent){
+                    MessageBox.Show("Unfortunately, "+Program.BrandName+" could not load the "+name+" file. The program will continue running with limited functionality.\r\n\r\n"+ex.Message, Program.BrandName+" Has Failed :(", MessageBoxButtons.OK, MessageBoxIcon.Error);
+                }
+
                 return null;
             }
         }
diff --git a/Resources/Scripts/pages/error.html b/Resources/Scripts/pages/error.html
new file mode 100644
index 00000000..e28a564a
--- /dev/null
+++ b/Resources/Scripts/pages/error.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style type="text/css">
+      body {
+        color: #e1e8ed;
+        background-color: #1c6399;
+        font-family: Helvetica, Arial, Verdana, sans-serif;
+        font-weight: 300;
+        font-size: 24px;
+        
+        width: 100%;
+        height: 100%;
+        margin: 0;
+        position: absolute;
+        display: table;
+      }
+      
+      center {
+        display: table-cell;
+        vertical-align: middle;
+      }
+      
+      h1 {
+        margin: 0;
+      }
+      
+      p {
+        margin: 20px 0 24px;
+      }
+      
+      button {
+        width: 100px;
+        height: 35px;
+        border: 0;
+        margin: 0 2px;
+        font-size: 17px;
+      }
+    </style>
+  </head>
+  <body>
+    <center>
+      <h1>Connection Error</h1>
+      <p>{err}</p>
+      <button onclick="location.href = 'td:reload'">Retry</button>
+      <button onclick="location.href = 'td:exit'">Exit</button>
+    </center>
+  </body>
+</html>
diff --git a/TweetDck.csproj b/TweetDck.csproj
index da893f8c..ea480383 100644
--- a/TweetDck.csproj
+++ b/TweetDck.csproj
@@ -326,6 +326,7 @@
   <ItemGroup>
     <Content Include="Resources\Scripts\code.js" />
     <Content Include="Resources\Scripts\notification.js" />
+    <Content Include="Resources\Scripts\pages\error.html" />
     <Content Include="Resources\Scripts\plugins.browser.js" />
     <Content Include="Resources\Scripts\plugins.js" />
     <Content Include="Resources\Scripts\plugins.notification.js" />