diff --git a/Ryujinx.HLE/HOS/Applets/AppletManager.cs b/Ryujinx.HLE/HOS/Applets/AppletManager.cs
index 5d075882c0..a686a83284 100644
--- a/Ryujinx.HLE/HOS/Applets/AppletManager.cs
+++ b/Ryujinx.HLE/HOS/Applets/AppletManager.cs
@@ -1,4 +1,5 @@
 using Ryujinx.HLE.HOS.Applets.Browser;
+using Ryujinx.HLE.HOS.Applets.Error;
 using Ryujinx.HLE.HOS.Services.Am.AppletAE;
 using System;
 using System.Collections.Generic;
@@ -13,6 +14,7 @@ namespace Ryujinx.HLE.HOS.Applets
         {
             _appletMapping = new Dictionary<AppletId, Type>
             {
+                { AppletId.Error,            typeof(ErrorApplet)            },
                 { AppletId.PlayerSelect,     typeof(PlayerSelectApplet)     },
                 { AppletId.Controller,       typeof(ControllerApplet)       },
                 { AppletId.SoftwareKeyboard, typeof(SoftwareKeyboardApplet) },
diff --git a/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs b/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs
new file mode 100644
index 0000000000..c78cbf3160
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs
@@ -0,0 +1,171 @@
+using LibHac.Common;
+using LibHac.Fs;
+using LibHac.Fs.Fsa;
+using LibHac.FsSystem;
+using LibHac.FsSystem.NcaUtils;
+using Ryujinx.Common.Logging;
+using Ryujinx.HLE.FileSystem;
+using Ryujinx.HLE.HOS.Services.Am.AppletAE;
+using Ryujinx.HLE.HOS.SystemState;
+using System;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace Ryujinx.HLE.HOS.Applets.Error
+{
+    internal class ErrorApplet : IApplet
+    {
+        private const long ErrorMessageBinaryTitleId = 0x0100000000000801;
+
+        private Horizon           _horizon;
+        private AppletSession     _normalSession;
+        private CommonArguments   _commonArguments;
+        private ErrorCommonHeader _errorCommonHeader;
+        private byte[]            _errorStorage;
+
+        public event EventHandler AppletStateChanged;
+
+        public ErrorApplet(Horizon horizon)
+        {
+            _horizon = horizon;
+        }
+
+        public ResultCode Start(AppletSession normalSession,
+                                AppletSession interactiveSession)
+        {
+            _normalSession   = normalSession;
+            _commonArguments = IApplet.ReadStruct<CommonArguments>(_normalSession.Pop());
+
+            Logger.Info?.PrintMsg(LogClass.ServiceAm, $"ErrorApplet version: 0x{_commonArguments.AppletVersion:x8}");
+
+            _errorStorage      = _normalSession.Pop();
+            _errorCommonHeader = IApplet.ReadStruct<ErrorCommonHeader>(_errorStorage);
+            _errorStorage      = _errorStorage.Skip(Marshal.SizeOf(typeof(ErrorCommonHeader))).ToArray();
+
+            switch (_errorCommonHeader.Type)
+            {
+                case ErrorType.ErrorCommonArg:
+                    {
+                        ParseErrorCommonArg();
+
+                        break;
+                    }
+                default: throw new NotImplementedException($"ErrorApplet type {_errorCommonHeader.Type} is not implemented.");
+            }
+
+            AppletStateChanged?.Invoke(this, null);
+
+            return ResultCode.Success;
+        }
+
+        private (uint module, uint description) HexToResultCode(uint resultCode)
+        {
+            return ((resultCode & 0x1FF) + 2000, (resultCode >> 9) & 0x3FFF);
+        }
+
+        private string SystemLanguageToLanguageKey(SystemLanguage systemLanguage)
+        {
+            return systemLanguage switch
+            {
+                SystemLanguage.Japanese             => "ja",
+                SystemLanguage.AmericanEnglish      => "en-US",
+                SystemLanguage.French               => "fr",
+                SystemLanguage.German               => "de",
+                SystemLanguage.Italian              => "it",
+                SystemLanguage.Spanish              => "es",
+                SystemLanguage.Chinese              => "zh-Hans",
+                SystemLanguage.Korean               => "ko",
+                SystemLanguage.Dutch                => "nl",
+                SystemLanguage.Portuguese           => "pt",
+                SystemLanguage.Russian              => "ru",
+                SystemLanguage.Taiwanese            => "zh-HansT",
+                SystemLanguage.BritishEnglish       => "en-GB",
+                SystemLanguage.CanadianFrench       => "fr-CA",
+                SystemLanguage.LatinAmericanSpanish => "es-419",
+                SystemLanguage.SimplifiedChinese    => "zh-Hans",
+                SystemLanguage.TraditionalChinese   => "zh-Hant",
+                _                                   => "en-US"
+            };
+        }
+
+        public string CleanText(string value)
+        {
+            return Regex.Replace(Encoding.Unicode.GetString(Encoding.UTF8.GetBytes(value)), @"[^\u0009\u000A\u000D\u0020-\u007E]", "");
+        }
+
+        private string GetMessageText(uint module, uint description, string key)
+        {
+            string binaryTitleContentPath = _horizon.ContentManager.GetInstalledContentPath(ErrorMessageBinaryTitleId, StorageId.NandSystem, NcaContentType.Data);
+
+            using (LibHac.Fs.IStorage ncaFileStream = new LocalStorage(_horizon.Device.FileSystem.SwitchPathToSystemPath(binaryTitleContentPath), FileAccess.Read, FileMode.Open))
+            {
+                Nca         nca          = new Nca(_horizon.Device.FileSystem.KeySet, ncaFileStream);
+                IFileSystem romfs        = nca.OpenFileSystem(NcaSectionType.Data, _horizon.FsIntegrityCheckLevel);
+                string      languageCode = SystemLanguageToLanguageKey(_horizon.State.DesiredSystemLanguage);
+                string      filePath     = "/" + Path.Combine(module.ToString(), $"{description:0000}", $"{languageCode}_{key}").Replace(@"\", "/");
+
+                if (romfs.FileExists(filePath))
+                {
+                    romfs.OpenFile(out IFile binaryFile, filePath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
+
+                    StreamReader reader = new StreamReader(binaryFile.AsStream());
+
+                    return CleanText(reader.ReadToEnd());
+                }
+                else
+                {
+                    return "";
+                }
+            }
+        }
+
+        private string[] GetButtonsText(uint module, uint description, string key)
+        {
+            string buttonsText = GetMessageText(module, description, key);
+
+            return (buttonsText == "") ? null : buttonsText.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
+        }
+
+        private void ParseErrorCommonArg()
+        {
+            ErrorCommonArg errorCommonArg = IApplet.ReadStruct<ErrorCommonArg>(_errorStorage);
+
+            uint module      = errorCommonArg.Module;
+            uint description = errorCommonArg.Description;
+
+            if (_errorCommonHeader.MessageFlag == 0)
+            {
+                (module, description) = HexToResultCode(errorCommonArg.ResultCode);
+            }
+
+            string message = GetMessageText(module, description, "DlgMsg");
+        
+            if (message == "")
+            {
+                message = "An error has occured.\n\n"
+                        + "Please try again later.\n\n"
+                        + "If the problem persists, please refer to the Ryujinx website.\n"
+                        + "www.ryujinx.org";
+            }
+
+            string[] buttons = GetButtonsText(module, description, "DlgBtn");
+
+            bool showDetails = _horizon.Device.UiHandler.DisplayErrorAppletDialog($"Error Code: {module}-{description:0000}", "\n" + message, buttons);
+            if (showDetails)
+            {
+                message = GetMessageText(module, description, "FlvMsg");
+                buttons = GetButtonsText(module, description, "FlvBtn");
+
+                _horizon.Device.UiHandler.DisplayErrorAppletDialog($"Details: {module}-{description:0000}", "\n" + message, buttons);
+            }
+        }
+
+        public ResultCode GetResult()
+        {
+            return ResultCode.Success;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Applets/Error/ErrorCommonArg.cs b/Ryujinx.HLE/HOS/Applets/Error/ErrorCommonArg.cs
new file mode 100644
index 0000000000..530a2ad8b0
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Applets/Error/ErrorCommonArg.cs
@@ -0,0 +1,12 @@
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Applets.Error
+{
+    [StructLayout(LayoutKind.Sequential, Pack = 1)]
+    struct ErrorCommonArg
+    {
+        public uint Module;
+        public uint Description;
+        public uint ResultCode;
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Applets/Error/ErrorCommonHeader.cs b/Ryujinx.HLE/HOS/Applets/Error/ErrorCommonHeader.cs
new file mode 100644
index 0000000000..b93cdd4f1e
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Applets/Error/ErrorCommonHeader.cs
@@ -0,0 +1,17 @@
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Applets.Error
+{
+    [StructLayout(LayoutKind.Sequential, Pack = 1)]
+    struct ErrorCommonHeader
+    {
+        public ErrorType Type;
+        public byte      JumpFlag;
+        public byte      ReservedFlag1;
+        public byte      ReservedFlag2;
+        public byte      ReservedFlag3;
+        public byte      ContextFlag;
+        public byte      MessageFlag;
+        public byte      ContextFlag2;
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Applets/Error/ErrorType.cs b/Ryujinx.HLE/HOS/Applets/Error/ErrorType.cs
new file mode 100644
index 0000000000..f06af1d3cf
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Applets/Error/ErrorType.cs
@@ -0,0 +1,13 @@
+namespace Ryujinx.HLE.HOS.Applets.Error
+{
+    enum ErrorType : byte
+    {
+        ErrorCommonArg,
+        SystemErrorArg,
+        ApplicationErrorArg,
+        ErrorEulaArg,
+        ErrorPctlArg,
+        ErrorRecordArg,
+        SystemUpdateEulaArg = 8
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/IHostUiHandler.cs b/Ryujinx.HLE/IHostUiHandler.cs
index 8e9bfc773e..b85fc356ae 100644
--- a/Ryujinx.HLE/IHostUiHandler.cs
+++ b/Ryujinx.HLE/IHostUiHandler.cs
@@ -31,5 +31,10 @@ namespace Ryujinx.HLE
         /// <param name="kind">The program kind.</param>
         /// <param name="value">The value associated to the <paramref name="kind"/>.</param>
         void ExecuteProgram(Switch device, ProgramSpecifyKind kind, ulong value);
+
+        /// Displays a Message Dialog box specific to Error Applet and blocks until it is closed.
+        /// </summary>
+        /// <returns>False when OK is pressed, True when another button (Details) is pressed.</returns>
+        bool DisplayErrorAppletDialog(string title, string message, string[] buttonsText);
     }
 }
\ No newline at end of file
diff --git a/Ryujinx/Ui/ErrorAppletDialog.cs b/Ryujinx/Ui/ErrorAppletDialog.cs
new file mode 100644
index 0000000000..f7a548b3e8
--- /dev/null
+++ b/Ryujinx/Ui/ErrorAppletDialog.cs
@@ -0,0 +1,32 @@
+using Gtk;
+using System.Reflection;
+
+namespace Ryujinx.Ui
+{
+    internal class ErrorAppletDialog : MessageDialog
+    {
+        internal static bool _isExitDialogOpen = false;
+
+        public ErrorAppletDialog(Window parentWindow, DialogFlags dialogFlags, MessageType messageType, string[] buttons) : base(parentWindow, dialogFlags, messageType, ButtonsType.None, null)
+        {
+            Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
+
+            int responseId = 0;
+
+            if (buttons != null)
+            {
+                foreach (string buttonText in buttons)
+                {
+                    AddButton(buttonText, responseId);
+                    responseId++;
+                }
+            }
+            else
+            {
+                AddButton("OK", 0);
+            }
+            
+            ShowAll();
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/Ui/GtkHostUiHandler.cs b/Ryujinx/Ui/GtkHostUiHandler.cs
index fd193dd7c8..12ba81c445 100644
--- a/Ryujinx/Ui/GtkHostUiHandler.cs
+++ b/Ryujinx/Ui/GtkHostUiHandler.cs
@@ -128,5 +128,56 @@ namespace Ryujinx.Ui
             device.UserChannelPersistence.ExecuteProgram(kind, value);
             MainWindow.GlWidget?.Exit();
         }
+
+        public bool DisplayErrorAppletDialog(string title, string message, string[] buttons)
+        {
+            ManualResetEvent dialogCloseEvent = new ManualResetEvent(false);
+            bool showDetails = false;
+
+            Application.Invoke(delegate
+            {
+                try
+                {
+                    ErrorAppletDialog msgDialog = new ErrorAppletDialog(_parent, DialogFlags.DestroyWithParent, MessageType.Error, buttons)
+                    {
+                        Title          = title,
+                        Text           = message,
+                        UseMarkup      = true,
+                        WindowPosition = WindowPosition.CenterAlways
+                    };
+
+                    msgDialog.SetDefaultSize(400, 0);
+
+                    msgDialog.Response += (object o, ResponseArgs args) =>
+                    {
+                        if (buttons != null)
+                        {
+                            if (buttons.Length > 1)
+                            {
+                                if (args.ResponseId != (ResponseType)(buttons.Length - 1))
+                                {
+                                    showDetails = true;
+                                }
+                            }
+                        }
+
+                        dialogCloseEvent.Set();
+                        msgDialog?.Dispose();
+                    };
+
+                    msgDialog.Show();
+                }
+                catch (Exception e)
+                {
+                    Logger.Error?.Print(LogClass.Application, $"Error displaying ErrorApplet Dialog: {e}");
+
+                    dialogCloseEvent.Set();
+                }
+            });
+
+            dialogCloseEvent.WaitOne();
+
+            return showDetails;
+        }
     }
 }