diff --git a/AKModel/templates/admin/AKModel/status.html b/AKModel/templates/admin/AKModel/status.html
index ee84a94ac5aeb0d9d7de0c08db3811bb84d64809..db22d935ae7d82590c6c6c4e9491bdc577ce0c11 100644
--- a/AKModel/templates/admin/AKModel/status.html
+++ b/AKModel/templates/admin/AKModel/status.html
@@ -74,6 +74,10 @@
 
                     <a class="btn btn-success"
                        href="{% url 'admin:schedule' event_slug=event.slug %}">{% trans "Scheduling" %}</a>
+                    {% if "AKScheduling | is_installed" %}
+                        <a class="btn btn-success"
+                       href="{% url 'admin:constraint-violations' slug=event.slug %}">{% trans "Constraint Violations" %} <span class="badge badge-secondary">{{ event.constraintviolation_set.count }}</span></a>
+                    {% endif %}
                     <a class="btn btn-success"
                        href="{% url 'admin:tracks_manage' event_slug=event.slug %}">{% trans "Manage ak tracks" %}</a>
                     <a class="btn btn-success"
diff --git a/AKScheduling/locale/de_DE/LC_MESSAGES/django.po b/AKScheduling/locale/de_DE/LC_MESSAGES/django.po
index f25c002dbd9be02bcac1bd45292140a48688de0d..5ed003e89f16deaac8e309561323c1cb974345d0 100644
--- a/AKScheduling/locale/de_DE/LC_MESSAGES/django.po
+++ b/AKScheduling/locale/de_DE/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-04-29 22:48+0000\n"
+"POT-Creation-Date: 2021-05-09 18:23+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,49 +17,92 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
+#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:11
 #: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:11
 #: AKScheduling/templates/admin/AKScheduling/scheduling.html:10
 msgid "Scheduling for"
 msgstr "Scheduling für"
 
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:126
+#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:74
+#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:128
+msgid "No violations"
+msgstr "Keine Verletzungen"
+
+#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:81
+msgid "Cannot load current violations from server"
+msgstr "Kann die aktuellen Verletzungen nicht vom Server laden"
+
+#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:106
+msgid "Violation(s)"
+msgstr "Verletzung(en)"
+
+#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:109
+msgid "Auto reload?"
+msgstr "Automatisch neu laden?"
+
+#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:113
+msgid "Reload now"
+msgstr "Jetzt neu laden"
+
+#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:118
+msgid "Violation"
+msgstr "Verletzung"
+
+#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:119
+msgid "Problem"
+msgstr "Problem"
+
+#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:120
+msgid "Details"
+msgstr "Details"
+
+#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:121
+msgid "Since"
+msgstr "Seit"
+
+#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:134
+#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:243
+#: AKScheduling/templates/admin/AKScheduling/scheduling.html:197
+#: AKScheduling/templates/admin/AKScheduling/unscheduled.html:34
+msgid "Event Status"
+msgstr "Event-Status"
+
+#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:136
+msgid "Scheduling"
+msgstr "Scheduling"
+
+#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:129
 msgid "Name of new ak track"
 msgstr "Name des neuen AK-Tracks"
 
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:142
+#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:145
 msgid "Could not create ak track"
 msgstr "Konnte neuen AK-Track nicht anlegen"
 
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:168
+#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:171
 msgid "Could not update ak track name"
 msgstr "Konnte Namen des AK-Tracks nicht ändern"
 
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:174
+#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:177
 msgid "Do you really want to delete this ak track?"
 msgstr "Soll dieser AK-Track wirklich gelöscht werden?"
 
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:188
+#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:191
 msgid "Could not delete ak track"
 msgstr "AK-Track konnte nicht gelöscht werden"
 
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:200
+#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:203
 msgid "Manage AK Tracks"
 msgstr "AK-Tracks verwalten"
 
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:201
+#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:204
 msgid "Add ak track"
 msgstr "AK-Track hinzufügen"
 
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:206
+#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:209
 msgid "AKs without track"
 msgstr "AKs ohne Track"
 
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:240
-#: AKScheduling/templates/admin/AKScheduling/scheduling.html:197
-#: AKScheduling/templates/admin/AKScheduling/unscheduled.html:34
-msgid "Event Status"
-msgstr "Event-Status"
-
 #: AKScheduling/templates/admin/AKScheduling/scheduling.html:87
 msgid "Day (Horizontal)"
 msgstr "Tag (horizontal)"
diff --git a/AKScheduling/templates/admin/AKScheduling/constraint_violations.html b/AKScheduling/templates/admin/AKScheduling/constraint_violations.html
new file mode 100644
index 0000000000000000000000000000000000000000..8645c192829c9bc58f91b45e78d1be2819b2892e
--- /dev/null
+++ b/AKScheduling/templates/admin/AKScheduling/constraint_violations.html
@@ -0,0 +1,137 @@
+{% extends "admin/base_site.html" %}
+{% load tags_AKModel %}
+
+{% load i18n %}
+{% load l10n %}
+{% load tz %}
+{% load static %}
+{% load tags_AKPlan %}
+{% load fontawesome_5 %}
+
+{% block title %}{% trans "Scheduling for" %} {{event}}{% endblock %}
+
+{% block extrahead %}
+    {{ block.super }}
+
+    <script>
+        document.addEventListener('DOMContentLoaded', function () {
+            // CSRF Protection/Authentication
+            function getCookie(name) {
+                let cookieValue = null;
+                if (document.cookie && document.cookie !== '') {
+                    const cookies = document.cookie.split(';');
+                    for (let i = 0; i < cookies.length; i++) {
+                        const cookie = cookies[i].trim();
+                        // Does this cookie string begin with the name we want?
+                        if (cookie.substring(0, name.length + 1) === (name + '=')) {
+                            cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
+                            break;
+                        }
+                    }
+                }
+                return cookieValue;
+            }
+
+            const csrftoken = getCookie('csrftoken');
+
+            function csrfSafeMethod(method) {
+                // these HTTP methods do not require CSRF protection
+                return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
+            }
+
+            $.ajaxSetup({
+                beforeSend: function (xhr, settings) {
+                    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
+                        xhr.setRequestHeader("X-CSRFToken", csrftoken);
+                    }
+                }
+            });
+
+            // (Re-)Load constraint violations using AJAX and visualize using violation count badge and violation table
+            function reload() {
+                $.ajax({
+                       url: "{% url "model:scheduling-constraint-violations-list" event_slug=event.slug %}",
+                        type: 'GET',
+                        success: function (response) {
+                           console.log(response);
+
+                           let table_html = '';
+
+                           if(response.length > 0) {
+                               // Update violation count badge
+                               $('#violationCountBadge').html(response.length).removeClass('badge-success').addClass('badge-warning');
+
+                               // Update violations table
+                               for(let i=0;i<response.length;i++) {
+                                   table_html += "<tr><td>" + response[i].level_display + "</td><td>" + response[i].type_display + "</td><td>" + response[i].details + "</td><td>" + response[i].timestamp_display + "</td><td></td></tr>";
+                               }
+                           }
+                           else {
+                               // Update violation count badge
+                               $('#violationCountBadge').html(0).removeClass('badge-warning').addClass('badge-success');
+
+                               // Update violations table
+                               table_html ='<tr class="text-muted"><td colspan="5" class="text-center">{% trans "No violations" %}</td></tr>'
+                           }
+
+                           // Show violation list (potentially empty) in violations table
+                           $('#violationsTableBody').html(table_html);
+                        },
+                        error: function (response) {
+                           alert("{% trans 'Cannot load current violations from server' %}");
+                        }
+                   });
+            }
+            reload();
+
+            // Bind reload button
+            $('#btnReloadNow').click(reload);
+
+            // Toggle automatic reloading (every 30 s) based on checkbox
+            let autoReloadInterval = undefined;
+            $('#cbxAutoReload').change(function () {
+                if(this.checked) {
+                    autoReloadInterval = setInterval(reload, 30*1000);
+                }
+                else {
+                    if(autoReloadInterval !== undefined)
+                        clearInterval(autoReloadInterval);
+                }
+            });
+        });
+    </script>
+{% endblock extrahead %}
+
+{% block content %}
+    <h4 class="mt-4 mb-4"><span id="violationCountBadge" class="badge badge-success">0</span> {% trans "Violation(s)" %}</h4>
+
+    <input type="checkbox" id="cbxAutoReload">
+    <label for="cbxAutoReload">{% trans "Auto reload?" %}</label>
+
+    <br>
+
+    <a href="#" id="btnReloadNow" class="btn btn-info">{% fa5_icon "sync-alt" "fas" %} {% trans "Reload now" %}</a>
+
+    <table class="table table-striped mt-4 mb-4">
+        <thead>
+            <tr>
+                <th>{% trans "Violation" %}</th>
+                <th>{% trans "Problem" %}</th>
+                <th>{% trans "Details" %}</th>
+                <th>{% trans "Since" %}</th>
+                <th></th>
+            </tr>
+        </thead>
+        <tbody id="violationsTableBody">
+        <tr class="text-muted">
+            <td colspan="5" class="text-center">
+                {% trans "No violations" %}
+            </td>
+        </tr>
+        </tbody>
+    </table>
+
+    <a href="{% url 'admin:event_status' event.slug %}">{% trans "Event Status" %}</a>
+    &middot;
+    <a href="{% url 'admin:schedule' event.slug %}">{% trans "Scheduling" %}</a>
+{% endblock %}
diff --git a/AKScheduling/urls.py b/AKScheduling/urls.py
index 171f3a1abdad4980f617fbbaab5781c516292fb1..93f490950d1b9299a90eb74e3ce0e0b76b2b518f 100644
--- a/AKScheduling/urls.py
+++ b/AKScheduling/urls.py
@@ -1,6 +1,7 @@
 from django.urls import path
 
-from AKScheduling.views import SchedulingAdminView, UnscheduledSlotsAdminView, TrackAdminView
+from AKScheduling.views import SchedulingAdminView, UnscheduledSlotsAdminView, TrackAdminView, \
+    ConstraintViolationsAdminView
 
 
 def get_admin_urls_scheduling(admin_site):
@@ -9,6 +10,8 @@ def get_admin_urls_scheduling(admin_site):
              name="schedule"),
         path('<slug:event_slug>/unscheduled/', admin_site.admin_view(UnscheduledSlotsAdminView.as_view()),
              name="slots_unscheduled"),
+        path('<slug:slug>/constraint-violations/', admin_site.admin_view(ConstraintViolationsAdminView.as_view()),
+             name="constraint-violations"),
         path('<slug:event_slug>/tracks/', admin_site.admin_view(TrackAdminView.as_view()),
              name="tracks_manage"),
     ]
diff --git a/AKScheduling/views.py b/AKScheduling/views.py
index 73719bd85f3c9dd62dc374e96cebd29b610d953b..9caadf5a9b9e247c103ecbf5c07cab227a35da1e 100644
--- a/AKScheduling/views.py
+++ b/AKScheduling/views.py
@@ -1,7 +1,7 @@
-from django.views.generic import ListView
+from django.views.generic import ListView, DetailView
 from django.utils.translation import gettext_lazy as _
 
-from AKModel.models import AKSlot, AKTrack
+from AKModel.models import AKSlot, AKTrack, Event
 from AKModel.views import AdminViewMixin, FilterByEventSlugMixin
 
 
@@ -47,3 +47,14 @@ class TrackAdminView(AdminViewMixin, FilterByEventSlugMixin, ListView):
         context = super().get_context_data(object_list=object_list, **kwargs)
         context["aks_without_track"] = self.event.ak_set.filter(track=None)
         return context
+
+
+class ConstraintViolationsAdminView(AdminViewMixin, DetailView):
+    template_name = "admin/AKScheduling/constraint_violations.html"
+    model = Event
+    context_object_name = "event"
+
+    def get_context_data(self, **kwargs):
+        context = super().get_context_data(**kwargs)
+        context["title"] = f"{_('Constraint violations for')} {context['event']}"
+        return context