diff --git a/include/errors/class_SimplePluginCheckError.inc b/include/errors/class_SimplePluginCheckError.inc
index 56e19de8afdf4adc53251a83e4f7ce9ad5e13768..dff0535ef99f4cebaf06ecc8f02b567641d04c8b 100644
--- a/include/errors/class_SimplePluginCheckError.inc
+++ b/include/errors/class_SimplePluginCheckError.inc
@@ -21,85 +21,8 @@
 /*! \class SimplePluginCheckError
     \brief Error returned by check method of SimplePlugin
 */
-class SimplePluginCheckError extends FusionDirectoryError
+class SimplePluginCheckError extends SimplePluginError
 {
-  protected $tab;
-  protected $attribute;
-
-  public function __construct (?object $origin, string $htmlMessage = '', int $code = 0, Throwable $previous = NULL)
-  {
-    if ($origin instanceof Attribute) {
-      $this->attribute  = $origin;
-      $this->tab        = $origin->getParent();
-    } else {
-      $this->attribute = NULL;
-      if ($origin instanceof SimpleTab) {
-        $this->tab = $origin;
-      } else {
-        $this->tab = NULL;
-      }
-    }
-
-    parent::__construct($htmlMessage, $code, $previous);
-  }
-
-  public function toArray (): array
-  {
-    $array = parent::toArray();
-
-    if (isset($this->tab)) {
-      $array['dn']  = $this->tab->parent->getBaseObject()->dn;
-      $array['tab'] = get_class($this->tab);
-    }
-
-    if (isset($this->attribute)) {
-      $array['attribute'] = $this->attribute->getLdapName();
-    }
-
-    return $array;
-  }
-
-  public function computeMsgDialogParameters (): array
-  {
-    $html = '';
-
-    if (isset($this->tab)) {
-      $html .= htmlescape($this->tab->parent->getBaseObject()->dn.' > ');
-      $html .= htmlescape($this->tab->parent->by_name[get_class($this->tab)].' > ');
-    }
-
-    if (isset($this->attribute)) {
-      $label = $this->attribute->getLabel();
-      if (empty($label)) {
-        $html .= '<i>'.htmlescape($this->attribute->getLdapName()).'</i>';
-      } else {
-        $html .= htmlescape($label);
-      }
-      $example = $this->attribute->getExample();
-    }
-
-    $html .= '<br/><br/>';
-
-    $html .= $this->htmlMessage;
-
-    /* Stylize example */
-    if (!empty($example)) {
-      $html .= '<br/><br/><i>'.sprintf(_('Example: %s'), htmlescape($example)).'</i> ';
-    }
-
-    $trace = $this->getTrace();
-
-    array_unshift(
-      $trace,
-      [
-        'file' => $this->getFile(),
-        'line' => $this->getLine(),
-      ]
-    );
-
-    return [_('Error'), $html, ERROR_DIALOG, $trace];
-  }
-
   /*!
    * \brief Format error message for invalid value
    *
diff --git a/include/errors/class_SimplePluginError.inc b/include/errors/class_SimplePluginError.inc
new file mode 100644
index 0000000000000000000000000000000000000000..a64922df6470305d98b8d7382e52bf3610ffa81f
--- /dev/null
+++ b/include/errors/class_SimplePluginError.inc
@@ -0,0 +1,112 @@
+<?php
+/*
+  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
+  Copyright (C) 2019-2020  FusionDirectory
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+/*! \class SimplePluginError
+    \brief Error returned by any method of SimplePlugin
+*/
+class SimplePluginError extends FusionDirectoryError
+{
+  protected $object;
+  protected $tab;
+  protected $attribute;
+
+  public function __construct (?object $origin, string $htmlMessage = '', int $code = 0, Throwable $previous = NULL)
+  {
+    if ($origin instanceof Attribute) {
+      $this->attribute  = $origin;
+      $this->tab        = $origin->getParent();
+      $this->object     = $this->tab->parent;
+    } else {
+      $this->attribute = NULL;
+      if ($origin instanceof SimpleTab) {
+        $this->tab    = $origin;
+        $this->object = $this->tab->parent;
+      } else {
+        $this->tab    = NULL;
+        $this->object = $origin;
+      }
+    }
+
+    parent::__construct($htmlMessage, $code, $previous);
+  }
+
+  public function toArray (): array
+  {
+    $array = parent::toArray();
+
+    if (isset($this->object)) {
+      $array['dn']  = $this->object->getBaseObject()->dn;
+    }
+
+    if (isset($this->tab)) {
+      $array['tab'] = get_class($this->tab);
+    }
+
+    if (isset($this->attribute)) {
+      $array['attribute'] = $this->attribute->getLdapName();
+    }
+
+    return $array;
+  }
+
+  public function computeMsgDialogParameters (): array
+  {
+    $html = '';
+
+    if (isset($this->object)) {
+      $html .= htmlescape($this->object->getBaseObject()->dn.' > ');
+    }
+
+    if (isset($this->tab)) {
+      $html .= htmlescape($this->tab->parent->by_name[get_class($this->tab)].' > ');
+    }
+
+    if (isset($this->attribute)) {
+      $label = $this->attribute->getLabel();
+      if (empty($label)) {
+        $html .= '<i>'.htmlescape($this->attribute->getLdapName()).'</i>';
+      } else {
+        $html .= htmlescape($label);
+      }
+      $example = $this->attribute->getExample();
+    }
+
+    $html .= '<br/><br/>';
+
+    $html .= $this->htmlMessage;
+
+    /* Stylize example */
+    if (!empty($example)) {
+      $html .= '<br/><br/><i>'.sprintf(_('Example: %s'), htmlescape($example)).'</i> ';
+    }
+
+    $trace = $this->getTrace();
+
+    array_unshift(
+      $trace,
+      [
+        'file' => $this->getFile(),
+        'line' => $this->getLine(),
+      ]
+    );
+
+    return [_('Error'), $html, ERROR_DIALOG, $trace];
+  }
+}
diff --git a/include/errors/class_SimplePluginLdapError.inc b/include/errors/class_SimplePluginLdapError.inc
new file mode 100644
index 0000000000000000000000000000000000000000..001bd49ef2f63f04a0f21d4313c6843fb91f2a56
--- /dev/null
+++ b/include/errors/class_SimplePluginLdapError.inc
@@ -0,0 +1,103 @@
+<?php
+/*
+  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
+  Copyright (C) 2019-2020  FusionDirectory
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+/*! \class SimplePluginLdapError
+    \brief Error returned by an LDAP operation called from SimplePlugin
+*/
+class SimplePluginLdapError extends SimplePluginError
+{
+  protected $dn;
+  protected $operation;
+
+  public function __construct ($origin, string $dn = NULL, int $operation = NULL, string $ldapError = '', int $code = 0, Throwable $previous = NULL)
+  {
+    $this->dn         = $dn;
+    $this->operation  = $operation;
+
+    parent::__construct($origin, htmlescape($ldapError), $code, $previous);
+  }
+
+  public function toArray (): array
+  {
+    $array = parent::toArray();
+
+    $typemap = [1 => 'read','add','modify','delete','search','authentication'];
+
+    $array['dn'] = $this->dn;
+    if (isset($this->operation)) {
+      $array['operation'] = $typemap[$this->operation];
+    }
+    $array['errno'] = $this->getCode();
+
+    return $array;
+  }
+
+  public function computeMsgDialogParameters (): array
+  {
+    $html = '';
+
+    if (isset($this->object)) {
+      $html .= htmlescape($this->object->getBaseObject()->dn.' > ');
+    }
+
+    if (isset($this->tab)) {
+      $html .= htmlescape($this->tab->parent->by_name[get_class($this->tab)].' > ');
+    }
+
+    if (isset($this->attribute)) {
+      $label = $this->attribute->getLabel();
+      if (empty($label)) {
+        $html .= '<i>'.htmlescape($this->attribute->getLdapName()).'</i>';
+      } else {
+        $html .= htmlescape($label);
+      }
+    }
+
+    $html .= '<br/><br/>';
+
+    /* Assign headline depending on type */
+    $typemap = [1 => _('read operation'), _('add operation'), _('modify operation'),
+        _('delete operation'), _('search operation'), _('authentication')];
+
+    if (isset($this->operation)) {
+      $html .= htmlescape(sprintf(_('LDAP %s failed!'), $typemap[$this->operation]));
+    } else {
+      $html .= htmlescape(_('LDAP operation failed!'));
+    }
+
+    if (!empty($this->dn)) {
+      $html .= '<br/><br/><i>'.htmlescape(_('Object')).':</i> '.htmlescape($this->dn);
+    }
+
+    $html .= '<br/><br/><i>'.htmlescape(_('Error')).':</i> '.$this->htmlMessage;
+
+    $trace = $this->getTrace();
+
+    array_unshift(
+      $trace,
+      [
+        'file' => $this->getFile(),
+        'line' => $this->getLine(),
+      ]
+    );
+
+    return [_('Error'), $html, ERROR_DIALOG, $trace];
+  }
+}
diff --git a/include/simpleplugin/class_simplePlugin.inc b/include/simpleplugin/class_simplePlugin.inc
index deb055b4465e16f0c4ff4444c7f245644c12d746..3a07f6c551d32bc92628606a8b24077c47519031 100644
--- a/include/simpleplugin/class_simplePlugin.inc
+++ b/include/simpleplugin/class_simplePlugin.inc
@@ -1376,14 +1376,24 @@ class simplePlugin implements SimpleTab
     $ldap = $config->get_ldap_link();
     if ($this->mainTab && !$this->initially_was_account) {
       if ($ldap->dn_exists($this->dn)) {
-        return [sprintf(_('There is already an entry with the same dn : %s'), $this->dn)];
+        return [
+          new SimplePluginError(
+            $this,
+            htmlescape(sprintf(_('There is already an entry with the same dn: %s'), $this->dn))
+          )
+        ];
       }
       $ldap->cd($config->current['BASE']);
       $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $this->dn));
       $action = 'add';
     } else {
       if (!$ldap->dn_exists($this->dn)) {
-        return [sprintf(_('The entry %s is not existing'), $this->dn)];
+        return [
+          new SimplePluginError(
+            $this,
+            htmlescape(sprintf(_('The entry %s is not existing'), $this->dn))
+          )
+        ];
       }
       $action = 'modify';
     }
@@ -1394,7 +1404,15 @@ class simplePlugin implements SimpleTab
 
     /* Check for errors */
     if (!$ldap->success()) {
-      return [msgPool::ldaperror($this->ldap_error, $this->dn, 0, get_class())];
+      return [
+        new SimplePluginLdapError(
+          $this,
+          $this->dn,
+          ($action == 'modify' ? LDAP_MOD : LDAP_ADD),
+          $ldap->get_error(),
+          $ldap->get_errno()
+        )
+      ];
     }
     return [];
   }
diff --git a/include/simpleplugin/class_simpleTabs.inc b/include/simpleplugin/class_simpleTabs.inc
index ba4bfcec44dab503c0e801274b7befb4018b2508..83e88d9059df9c94996c79145d04b82858fb14af 100644
--- a/include/simpleplugin/class_simpleTabs.inc
+++ b/include/simpleplugin/class_simpleTabs.inc
@@ -342,7 +342,7 @@ class simpleTabs
   /*!
    * \brief Check
    */
-  public function check ()
+  public function check (): array
   {
     global $config;
     $messages = [];
@@ -354,7 +354,10 @@ class simpleTabs
       $ldap->search($filter, ['dn']);
       while ($attrs = $ldap->fetch()) {
         if ($attrs['dn'] != $this->getBaseObject()->dn) {
-          $messages[] = msgPool::duplicated($this->getBaseObject()->attributesAccess['_template_cn']->getLabel(), $attrs['dn']);
+          $messages[] = new SimplePluginCheckError(
+            $this->getBaseObject()->attributesAccess['_template_cn'],
+            htmlescape(msgPool::duplicated($this->getBaseObject()->attributesAccess['_template_cn']->getLabel(), $attrs['dn']))
+          );
         }
       }
       return $messages;
@@ -402,7 +405,12 @@ class simpleTabs
       logging::debug(DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $new_dn, 'Saving');
     } catch (FusionDirectoryException $e) {
       return [
-        sprintf(_('Failed to compute DN for object: %s'), $e->getMessage())
+        new SimplePluginError(
+          $baseobject,
+          htmlescape(sprintf(_('Failed to compute DN for object: %s'), $e->getMessage())),
+          0,
+          $e
+        )
       ];
     }
 
@@ -419,7 +427,10 @@ class simpleTabs
         if (($error = $baseobject->move($this->dn, $new_dn)) === TRUE) {
           $this->dn = $new_dn;
         } else {
-          $errors[] = sprintf(_('Move from "%s" to "%s" failed: %s'), $this->dn, $new_dn, $error);
+          $errors[] = new SimplePluginError(
+            $baseobject,
+            htmlescape(sprintf(_('Move from "%s" to "%s" failed: %s'), $this->dn, $new_dn, $error))
+          );
           return $errors;
         }
       }