diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 8b55fc8dd21619cd55817143df53fd08627e9fe0..f6162fac619ddd09347f009f2a777cad9807fc32 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -14,6 +14,7 @@ Added
 
 * Add fuzzy matching mode for searching course groups: If no 100 % match is found,
   the importer will search a match by a subset of parent groups.
+* Register data match failures as data check problems.
 
 Changed
 ~~~~~~~
diff --git a/aleksis/apps/untis/data_checks.py b/aleksis/apps/untis/data_checks.py
new file mode 100644
index 0000000000000000000000000000000000000000..fc7b47512c6302e1e17e3dbfbd2a597a8712d446
--- /dev/null
+++ b/aleksis/apps/untis/data_checks.py
@@ -0,0 +1,36 @@
+from django.utils.translation import gettext_lazy as _
+
+from aleksis.core.data_checks import DataCheck, IgnoreSolveOption
+
+
+class CourseGroupNotFoundAndCreated(DataCheck):
+    name = "untis_mysql_course_group_not_found_and_created"
+    verbose_name = _(
+        "Course groups created by the Untis import because no matching group has been found."
+    )
+    problem_name = _(
+        "The Untis import created a new course group because no matching group has been found."
+    )
+
+    solve_options = {IgnoreSolveOption.name: IgnoreSolveOption}
+
+    @classmethod
+    def run_check_data(cls):
+        pass
+
+
+class CourseGroupNotFoundAndNotCreated(DataCheck):
+    name = "untis_not_created_not_primary_source"
+    verbose_name = _(
+        "Course group not set by the Untis import because no matching group has been found."
+    )
+    problem_name = _(
+        "The Untis import didn't set a course group "
+        "for a lesson because no matching group has been found."
+    )
+
+    solve_options = {IgnoreSolveOption.name: IgnoreSolveOption}
+
+    @classmethod
+    def run_check_data(cls):
+        pass
diff --git a/aleksis/apps/untis/models.py b/aleksis/apps/untis/models.py
index c616ba84b71f5812668681ff4477a7b523719770..d29083f3edc034940ed444961821666e92adaaee 100644
--- a/aleksis/apps/untis/models.py
+++ b/aleksis/apps/untis/models.py
@@ -8,6 +8,8 @@ from django.utils.translation import gettext as _
 
 from aleksis.core.mixins import PureDjangoModel
 
+from .data_checks import CourseGroupNotFoundAndCreated, CourseGroupNotFoundAndNotCreated
+
 
 class Absence(models.Model, PureDjangoModel):
     school_id = models.IntegerField(
@@ -4244,6 +4246,8 @@ class Views(models.Model, PureDjangoModel):
 
 
 class GlobalPermissions(models.Model, PureDjangoModel):
+    data_checks = [CourseGroupNotFoundAndCreated, CourseGroupNotFoundAndNotCreated]
+
     class Meta:
         managed = False
         permissions = (("assign_subjects_to_groups", _("Can assign subjects to groups")),)
diff --git a/aleksis/apps/untis/preferences.py b/aleksis/apps/untis/preferences.py
index 36e54d9790f8c272e986d43528a833a1bcd98f16..d95f5bc30cb306d3bca40c0db60f682a26a86143 100644
--- a/aleksis/apps/untis/preferences.py
+++ b/aleksis/apps/untis/preferences.py
@@ -86,9 +86,24 @@ class UseCourseGroups(BooleanPreference):
     name = "use_course_groups"
     default = True
     verbose_name = _("Use course groups")
-    help_text = _(
-        "Build or search course groups for every course" " instead of setting classes as groups."
-    )
+    help_text = _("Search course groups for every course instead of setting classes as groups.")
+
+
+@site_preferences_registry.register
+class CreateCourseGroups(BooleanPreference):
+    section = untis_mysql
+    name = "create_course_groups"
+    default = True
+    verbose_name = _("Create non-existing course groups")
+    help_text = _("Only used if 'Use course groups' is enabled.")
+
+
+@site_preferences_registry.register
+class DataCheckNotFoundCourseGroups(BooleanPreference):
+    section = untis_mysql
+    name = "data_check_for_not_found_course_groups"
+    default = True
+    verbose_name = _("Register a data problem if a course group has been not found.")
 
 
 @site_preferences_registry.register
diff --git a/aleksis/apps/untis/util/mysql/importers/lessons.py b/aleksis/apps/untis/util/mysql/importers/lessons.py
index dc7aa154c85b4ca21c05030c53e7a49f9d25a81b..006fc497f3b57920e12237da04196912b2cc2abb 100644
--- a/aleksis/apps/untis/util/mysql/importers/lessons.py
+++ b/aleksis/apps/untis/util/mysql/importers/lessons.py
@@ -13,6 +13,7 @@ from aleksis.core import models as core_models
 from aleksis.core.util.core_helpers import get_site_preferences
 
 from .... import models as mysql_models
+from ....data_checks import CourseGroupNotFoundAndCreated, CourseGroupNotFoundAndNotCreated
 from ..util import (
     TQDM_DEFAULTS,
     compare_m2m,
@@ -120,6 +121,7 @@ def import_lessons(
                 c = classes_ref[class_id]
                 course_classes.append(c)
 
+            course_group_not_found_and_not_created = False
             if get_site_preferences()["untis_mysql__use_course_groups"]:
                 # Negative import_ref denotes a course group
                 group_import_ref = -int("{}{}".format(lesson_id, i))
@@ -132,7 +134,7 @@ def import_lessons(
                 ).filter(Q(school_term__isnull=True) | Q(school_term=validity_range.school_term))
 
                 # Check if found groups match
-                match = False
+                course_group = None
                 for found_group in qs:
                     if compare_m2m(course_classes, found_group.parent_groups.all()) and compare_m2m(
                         teachers, found_group.owners.all()
@@ -173,7 +175,11 @@ def import_lessons(
                                     )
 
                 changed = False
-                if not match:
+                register_data_check = get_site_preferences()[
+                    "untis_mysql__data_check_for_not_found_course_groups"
+                ]
+                if not course_group and get_site_preferences()["untis_mysql__create_course_groups"]:
+
                     # No matching group found
 
                     # Build names and refs for course groups
@@ -206,29 +212,40 @@ def import_lessons(
 
                         changed = True
 
-                # Update owners
-                course_group.owners.set(teachers)
+                    if created and register_data_check:
+                        # No match, new course group created, so create a data problem if activated
+                        CourseGroupNotFoundAndCreated.register_result(course_group)
+                elif register_data_check:
+                    # No match, create deactivated, so create a data problem later if activated
+                    course_group_not_found_and_not_created = True
+
+                if course_group:
+                    # Update owners
+                    course_group.owners.set(teachers)
+
+                    # Update import ref
+                    if course_group.import_ref_untis != group_import_ref:
+                        course_group.import_ref_untis = group_import_ref
+                        logger.info("    Import reference of course group updated")
+                        changed = True
 
-                # Update import ref
-                if course_group.import_ref_untis != group_import_ref:
-                    course_group.import_ref_untis = group_import_ref
-                    logger.info("    Import reference of course group updated")
-                    changed = True
+                    if course_group.subject != subject:
+                        course_group.subject = subject
+                        logger.info("    Subject reference of course group updated")
+                        changed = True
 
-                if course_group.subject != subject:
-                    course_group.subject = subject
-                    logger.info("    Subject reference of course group updated")
-                    changed = True
+                    if course_group.school_term != validity_range.school_term:
+                        course_group.school_term = validity_range.school_term
+                        logger.info("    School term reference of course group updated")
+                        changed = True
 
-                if course_group.school_term != validity_range.school_term:
-                    course_group.school_term = validity_range.school_term
-                    logger.info("    School term reference of course group updated")
-                    changed = True
+                    if changed:
+                        course_group.save()
 
-                if changed:
-                    course_group.save()
+                    groups = [course_group]
 
-                groups = [course_group]
+                else:
+                    groups = []
             else:
                 groups = course_classes
 
@@ -259,8 +276,13 @@ def import_lessons(
                 )
                 logger.info("    New lesson created")
 
+            if course_group_not_found_and_not_created:
+                # Register data problem here because before the lesson object is unknown
+                CourseGroupNotFoundAndNotCreated.register_result(lesson)
+
             # Sync groups
-            lesson.groups.set(groups)
+            if groups:
+                lesson.groups.set(groups)
 
             # Sync teachers
             lesson.teachers.set(teachers)
diff --git a/docs/admin/20_configuration.rst b/docs/admin/20_configuration.rst
index 9984da36cbdd7c181b4263f00c51f8d1da779a39..065dbf319fad22935f44ce1218d645ae9e2d7496 100644
--- a/docs/admin/20_configuration.rst
+++ b/docs/admin/20_configuration.rst
@@ -67,8 +67,15 @@ The way data are imported can be configured from the menu under
   existing rooms if Untis has different data.
 * **Update existing supervision areas:** This will update the values of
   already existing supervision areas if Untis has different data.
-* **Use course groups:** This will build or search course groups (groups
+* **Use course groups:** This will search course groups (groups
   for each subject in a class) instead of setting the classes as groups.
+* **Create non-existing course groups**: In combination with _Use course groups_ being enabled,
+  this will create new course groups if no matching group was found.
+* **Register a data problem if a course group has been not found:** When this is activated,
+  the import will register a data problem if no matching course group was found,
+  independent of whether a new course group was created or not.
+* **Ignore incomplete substitutions**: If this is activated, Untis won't import any substitutions
+  which are not cancelled or without a new room, new teacher or new subject .
 
 Scheduling import tasks
 -----------------------