diff --git a/software/caddy-frontend/buildout.hash.cfg b/software/caddy-frontend/buildout.hash.cfg
index 33ffcde36bc268a9cc4f811db040d7b66cba502f..12b53db4878ad35983bd124540f71039c42fb69f 100644
--- a/software/caddy-frontend/buildout.hash.cfg
+++ b/software/caddy-frontend/buildout.hash.cfg
@@ -26,7 +26,7 @@ md5sum = 750e2b1c922bf14511a3bc8a42468b1b
 
 [template-apache-replicate]
 filename = instance-apache-replicate.cfg.in
-md5sum = e5e537052c533c6d6f1c2197428f77fd
+md5sum = aaac56847a966ec4f155cba10570bb3c
 
 [template-slave-list]
 filename = templates/apache-custom-slave-list.cfg.in
diff --git a/software/caddy-frontend/instance-apache-replicate.cfg.in b/software/caddy-frontend/instance-apache-replicate.cfg.in
index 2c07f30c35b1f59a9f2355be8afb39c871148d57..83274be91ebe6193bda393181d50fada9d41f215 100644
--- a/software/caddy-frontend/instance-apache-replicate.cfg.in
+++ b/software/caddy-frontend/instance-apache-replicate.cfg.in
@@ -66,24 +66,25 @@ context =
 
 {% set authorized_slave_string = slapparameter_dict.pop('-frontend-authorized-slave-string', '') %}
 {% set authorized_slave_list = [] %}
-{% set rejected_slave_list = [] %}
+{% set rejected_slave_dict = {} %}
 {% set used_host_list = [] %}
+{% set unauthorised_message = 'slave not authorised' %}
 {% for slave in slave_instance_list %}
-{%   set slave_dict = {'state': True} %}
+{%   set slave_error_list = [] %}
 {#   BBB: apache_custom_https AND apache_custom_http #}
 {%   set custom_domain = slave.get('custom_domain') %}
 {%   if custom_domain and custom_domain in used_host_list %}
-{%      do slave_dict.__setitem__('state', False) %}
+{%      do slave_error_list.append('custom_domain %r clashes' % (custom_domain,)) %}
 {%   else %}
 {%      do used_host_list.append(custom_domain) %}
 {%   endif %}
 {%   if slave.get('server-alias') %}
 {%     for slave_alias in slave['server-alias'].split() %}
 {%       if not validators.domain(slave_alias) %}
-{%         do slave_dict.__setitem__('state', False) %}
+{%         do slave_error_list.append('server-alias %r not valid' % (slave_alias,)) %}
 {%       else %}
 {%         if slave_alias in used_host_list %}
-{%           do slave_dict.__setitem__('state', False) %}
+{%           do slave_error_list.append('server-alias %r clashes' % (slave_alias,)) %}
 {%         else %}
 {%           do used_host_list.append(slave_alias) %}
 {%         endif %}
@@ -93,20 +94,22 @@ context =
 {%   for key in ['caddy_custom_http', 'caddy_custom_https', 'apache_custom_http', 'apache_custom_https'] %}
 {%     if slave.get(key) %}
 {%       if not slave.get('slave_reference') in authorized_slave_string %}
-{%         do slave_dict.__setitem__('state', False) %}
+{%         if not unauthorised_message in slave_error_list %}
+{%           do slave_error_list.append(unauthorised_message) %}
+{%         endif %}
 {%       elif subprocess_module.call([caddy_custom_http_validator, slave[key]]) == 1 %}
-{%         do slave_dict.__setitem__('state', False) %}
+{%         do slave_error_list.append('slave %s configuration invalid' % (key,)) %}
 {%       endif %}
 {%     endif %}
 {%   endfor %} {# for key in ['caddy_custom_http', 'caddy_custom_https', 'apache_custom_http', 'apache_custom_https'] #}
 {%   if slave.get('url') %}
 {%     if subprocess_module.call([caddy_backend_url_validator, slave['url']]) == 1 %}
-{%       do slave_dict.__setitem__('state', False) %}
+{%       do slave_error_list.append('slave url %r invalid' % (slave['url'],)) %}
 {%     endif %}
 {%   endif %}
 {%   if slave.get('https-url') %}
 {%     if subprocess_module.call([caddy_backend_url_validator, slave['https-url']]) == 1 %}
-{%       do slave_dict.__setitem__('state', False) %}
+{%       do slave_error_list.append('slave https-url %r invalid' % (slave['https-url'],)) %}
 {%     endif %}
 {%   endif %}
 {%   if slave.get('ssl_key') and slave.get('ssl_crt') %}
@@ -115,18 +118,18 @@ context =
 {%     set key_modulus = key_popen.communicate(slave['ssl_key'])[0] | trim %}
 {%     set crt_modulus = crt_popen.communicate(slave['ssl_crt'])[0] | trim %}
 {%     if not key_modulus or key_modulus != crt_modulus  %}
-{%       do slave_dict.__setitem__('state', False) %}
+{%       do slave_error_list.append('slave ssl_key and ssl_crt does not match')  %}
 {%     endif %}
 {%   endif %}
 {%   if slave.get('custom_domain') %}
 {%     if not validators.domain(slave['custom_domain']) %}
-{%       do slave_dict.__setitem__('state', False) %}
+{%       do slave_error_list.append('custom_domain %r invalid' % (slave['custom_domain'],)) %}
 {%     endif %}
 {%   endif %}
-{%   if slave_dict['state'] %}
+{%   if len(slave_error_list) == 0 %}
 {%     do authorized_slave_list.append(slave) %}
 {%   else %}
-{%     do rejected_slave_list.append(slave.get('slave_reference')) %}
+{%     do rejected_slave_dict.__setitem__(slave.get('slave_reference'), slave_error_list) %}
 {%   endif %}
 {% endfor %}
 
@@ -177,8 +180,8 @@ recipe = slapos.cookbook:publish
 domain = {{ slapparameter_dict.get('domain') }}
 slave-amount = {{ slave_instance_list | length }}
 accepted-slave-amount = {{ authorized_slave_list | length }}
-rejected-slave-amount = {{ rejected_slave_list | length }}
-rejected-slave-list = {{ json_module.dumps(rejected_slave_list) }}
+rejected-slave-amount = {{ rejected_slave_dict | length }}
+rejected-slave-dict = {{ dumps(json_module.dumps(rejected_slave_dict)) }}
 
 #----------------------------
 #--
diff --git a/software/caddy-frontend/instance-output-schema.json b/software/caddy-frontend/instance-output-schema.json
index cbad7214cd0c1e684683d373da2f59e2f5d6bafd..d8c1746597f7636d1e35823f4a99d56d51852cbd 100644
--- a/software/caddy-frontend/instance-output-schema.json
+++ b/software/caddy-frontend/instance-output-schema.json
@@ -26,12 +26,12 @@
       "description": "User to access the monitor",
       "type": "string"
     },
-    "reject-slave-amount": {
+    "rejected-slave-amount": {
       "description": "Rejected Amount of Slaves allocated to the Instance which are not deployed",
       "type": "integer"
     },
-    "rejected-slave-list": {
-      "description": "List of slave instances references which are rejected",
+    "rejected-slave-dict": {
+      "description": "Dict of slaves which were rejected. Keys are slave references, values are lists of errors on slaves.",
       "type": "array"
     },
     "slave-amount": {
diff --git a/software/caddy-frontend/test/test.py b/software/caddy-frontend/test/test.py
index 0266ae40bdc0e9e2014b1b58a17e7ac990b385e2..b7295747ac5af9ae7033026401dc571faab84f2f 100644
--- a/software/caddy-frontend/test/test.py
+++ b/software/caddy-frontend/test/test.py
@@ -262,7 +262,7 @@ class TestMasterRequest(HttpFrontendTestCase, TestDataMixin):
         'accepted-slave-amount': '0',
         'rejected-slave-amount': '0',
         'slave-amount': '0',
-        'rejected-slave-list': '[]'},
+        'rejected-slave-dict': '{}'},
       parameter_dict
     )
 
@@ -296,7 +296,7 @@ class TestMasterRequestDomain(HttpFrontendTestCase, TestDataMixin):
         'accepted-slave-amount': '0',
         'rejected-slave-amount': '0',
         'slave-amount': '0',
-        'rejected-slave-list': '[]'
+        'rejected-slave-dict': '{}'
       },
       parameter_dict
     )
@@ -727,8 +727,10 @@ http://apachecustomhttpsaccepted.example.com:%%(http_port)s {
       'accepted-slave-amount': '33',
       'rejected-slave-amount': '2',
       'slave-amount': '35',
-      'rejected-slave-list':
-      '["_caddy_custom_http_s-rejected", "_apache_custom_http_s-rejected"]'}
+      'rejected-slave-dict':
+      '{"_apache_custom_http_s-rejected": ["slave not authorised"], '
+      '"_caddy_custom_http_s-rejected": ["slave not authorised"]}'
+    }
 
     self.assertEqual(
       expected_parameter_dict,
@@ -2638,7 +2640,11 @@ class TestMalformedBackenUrlSlave(SlaveHttpFrontendTestCase,
       'accepted-slave-amount': '1',
       'rejected-slave-amount': '2',
       'slave-amount': '3',
-      'rejected-slave-list': '["_url", "_https-url"]'}
+      'rejected-slave-dict':
+      '{"_https-url": ["slave https-url \\"https://[fd46::c2ae]:!py!u\'123123'
+      '\'\\" invalid"], "_url": ["slave url \\"https://[fd46::c2ae]:!py!u\''
+      '123123\'\\" invalid"]}'
+    }
 
     self.assertEqual(
       expected_parameter_dict,
@@ -2917,9 +2923,15 @@ https://www.google.com {}""",
       'accepted-slave-amount': '8',
       'rejected-slave-amount': '4',
       'slave-amount': '12',
-      'rejected-slave-list':
-      '["_caddy_custom_http_s-reject", "_ssl_key-ssl_crt-unsafe", '
-      '"_custom_domain-unsafe", "_server-alias-unsafe"]'}
+      'rejected-slave-dict':
+      '{"_caddy_custom_http_s-reject": ["slave caddy_custom_http '
+      'configuration invalid", "slave caddy_custom_https configuration '
+      'invalid"], "_server-alias-unsafe": ["server-alias \'${section:option}\''
+      ' not valid", "server-alias \'afterspace\' not valid"], '
+      '"_custom_domain-unsafe": ["custom_domain \'${section:option} '
+      'afterspace\\\\nafternewline\' invalid"], "_ssl_key-ssl_crt-unsafe": '
+      '["slave ssl_key and ssl_crt does not match"]}'
+    }
 
     self.assertEqual(
       expected_parameter_dict,
@@ -3286,7 +3298,11 @@ class TestDuplicateSiteKeyProtection(SlaveHttpFrontendTestCase, TestDataMixin):
       'accepted-slave-amount': '1',
       'rejected-slave-amount': '3',
       'slave-amount': '4',
-      'rejected-slave-list': '["_site_3", "_site_1", "_site_4"]'}
+      'rejected-slave-dict':
+      '{"_site_4": ["custom_domain clashes", "server-alias '
+      '\'duplicate.example.com\' clashes"], "_site_1": '
+      '["custom_domain clashes"], "_site_3": ["server-alias '
+      '\'duplicate.example.com\' clashes"]}'}
 
     self.assertEqual(
       expected_parameter_dict,