diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0d63406b65c1d466c69cd6e90593bc8ce3095734..89a998e7b8b2e8997bdf333f83cda2463de4219a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,8 +9,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Added ###
 
+* `apiutils.EntityMergeConflictError` class for unresesolvable merge conflicts
+  when merging two entities
+
 ### Changed ###
 
+* `apiutils.merge_entities` now raises an `EntityMergeConflictError` in case of
+  unresolvable merge conflicts.
+
 ### Deprecated ###
 
 ### Removed ###
diff --git a/src/caosdb/apiutils.py b/src/caosdb/apiutils.py
index 0862cf9f32575b9773bc16d845bb459d67b0140c..f3195b8e152f0cb13e5dab3e3a449b7bb36623b4 100644
--- a/src/caosdb/apiutils.py
+++ b/src/caosdb/apiutils.py
@@ -27,12 +27,13 @@
 Some simplified functions for generation of records etc.
 """
 
+import logging
 import sys
 import tempfile
 import warnings
+
 from collections.abc import Iterable
 from subprocess import call
-
 from typing import Optional, Any, Dict, List
 
 from caosdb.common.datatype import (BOOLEAN, DATETIME, DOUBLE, FILE, INTEGER,
@@ -40,8 +41,13 @@ from caosdb.common.datatype import (BOOLEAN, DATETIME, DOUBLE, FILE, INTEGER,
 from caosdb.common.models import (Container, Entity, File, Property, Query,
                                   Record, RecordType, execute_query,
                                   get_config, SPECIAL_ATTRIBUTES)
+from caosdb.exceptions import CaosDBException
 
-import logging
+
+class EntityMergeConflictError(CaosDBException):
+    """An error that is raised in case of an unresolvable conflict when merging
+    two entities.
+    """
 
 
 def new_record(record_type, name=None, description=None,
@@ -365,14 +371,15 @@ def empty_diff(old_entity: Entity, new_entity: Entity, compare_referenced_record
     return True
 
 
-def merge_entities(entity_a: Entity, entity_b: Entity, merge_references_with_empty_diffs=True, force=False):
-    """
-    Merge entity_b into entity_a such that they have the same parents and properties.
+def merge_entities(entity_a: Entity, entity_b: Entity, merge_references_with_empty_diffs=True,
+                   force=False):
+    """Merge entity_b into entity_a such that they have the same parents and properties.
 
-    datatype, unit, value, name and description will only be changed in entity_a if they
-    are None for entity_a and set for entity_b. If there is a corresponding value
-    for entity_a different from None a RuntimeError will be raised informing of an
-    unresolvable merge conflict.
+    datatype, unit, value, name and description will only be changed in entity_a
+    if they are None for entity_a and set for entity_b. If there is a
+    corresponding value for entity_a different from None, an
+    EntityMergeConflictError will be raised to inform about an unresolvable merge
+    conflict.
 
     The merge operation is done in place.
 
@@ -392,13 +399,18 @@ def merge_entities(entity_a: Entity, entity_b: Entity, merge_references_with_emp
     force : bool, optional
        If True, in case `entity_a` and `entity_b` have the same properties, the
        values of `entity_a` are replaced by those of `entity_b` in the merge.
-       If `False`, a RuntimeError is raised instead. Default is False.
+       If `False`, an EntityMergeConflictError is raised instead. Default is False.
 
     Returns
     -------
     entity_a : Entity
        The initial entity_a after the in-place merge
 
+    Raises
+    ------
+    EntityMergeConflictError
+        In case of an unresolvable merge conflict.
+
     """
 
     logging.warning(
@@ -433,8 +445,8 @@ def merge_entities(entity_a: Entity, entity_b: Entity, merge_references_with_emp
                         setattr(entity_a.get_property(key), attribute,
                                 diff_r2["properties"][key][attribute])
                     else:
-                        raise RuntimeError(
-                            f"Merge conflict:\nEntity a ({entity_a.id}, {entity_a.name}) "
+                        raise EntityMergeConflictError(
+                            f"Entity a ({entity_a.id}, {entity_a.name}) "
                             f"has a Property '{key}' with {attribute}="
                             f"{diff_r2['properties'][key][attribute]}\n"
                             f"Entity b ({entity_b.id}, {entity_b.name}) "
@@ -463,7 +475,9 @@ def merge_entities(entity_a: Entity, entity_b: Entity, merge_references_with_emp
                 # force overwrite
                 setattr(entity_a, special_attribute, sa_b)
             else:
-                raise RuntimeError("Merge conflict.")
+                raise EntityMergeConflictError(
+                    f"Conflict in special attribute {special_attribute}:\n"
+                    f"A: {sa_a}\nB: {sa_b}")
     return entity_a
 
 
diff --git a/unittests/test_apiutils.py b/unittests/test_apiutils.py
index 8026b7cd97e5e552eddf61b3f89c546933eaf579..9b87a743b201213feb49cfc660e006f2c6217387 100644
--- a/unittests/test_apiutils.py
+++ b/unittests/test_apiutils.py
@@ -30,7 +30,8 @@ import pytest
 import caosdb as db
 import caosdb.apiutils
 from caosdb.apiutils import (apply_to_ids, compare_entities, create_id_query,
-                             empty_diff, resolve_reference, merge_entities)
+                             empty_diff, EntityMergeConflictError,
+                             resolve_reference, merge_entities)
 
 from caosdb.common.models import SPECIAL_ATTRIBUTES
 
@@ -307,7 +308,7 @@ def test_merge_bug_conflict():
 
     r3 = db.Record()
     r3.add_property(name="C", value=4, datatype="INTEGER")
-    with pytest.raises(RuntimeError) as excinfo:
+    with pytest.raises(EntityMergeConflictError):
         merge_entities(r3, r2)
 
 
@@ -402,15 +403,13 @@ def test_wrong_merge_conflict_reference():
     rec_a.add_property(name=title_prop.name, value="Some dataset title")
 
     # this does not compare referenced records, so it will fail
-    with pytest.raises(RuntimeError) as re:
+    with pytest.raises(EntityMergeConflictError):
         merge_entities(rec_a, rec_b, merge_references_with_empty_diffs=False)
-    assert "Merge conflict" in str(re.value)
 
     # ... as should this, of course
     rec_b.get_property(license_rt.name).value.name = "Another license"
-    with pytest.raises(RuntimeError) as re:
+    with pytest.raises(EntityMergeConflictError) as re:
         merge_entities(rec_a, rec_b)
-    assert "Merge conflict" in str(re.value)
 
 
 def test_empty_diff():
@@ -484,9 +483,8 @@ def test_force_merge():
     recA = db.Record(name="A")
     recB = db.Record(name="B")
 
-    with pytest.raises(RuntimeError) as re:
+    with pytest.raises(EntityMergeConflictError):
         merge_entities(recA, recB)
-    assert "Merge conflict" in str(re.value)
 
     merge_entities(recA, recB, force=True)
     assert "B" == recA.name
@@ -499,9 +497,11 @@ def test_force_merge():
     recB = db.Record()
     recB.description = "something else"
 
-    with pytest.raises(RuntimeError) as re:
+    with pytest.raises(EntityMergeConflictError) as emce:
         merge_entities(recA, recB)
-    assert "Merge conflict" in str(re.value)
+    assert str(emce.value) == """Conflict in special attribute description:
+A: something
+B: something else"""
 
     merge_entities(recA, recB, force=True)
     assert recA.description == "something else"
@@ -514,9 +514,8 @@ def test_force_merge():
     recB = db.Record()
     recB.add_property(name="propA", value="something else")
 
-    with pytest.raises(RuntimeError) as re:
+    with pytest.raises(EntityMergeConflictError):
         merge_entities(recA, recB)
-    assert "Merge conflict" in str(re.value)
 
     merge_entities(recA, recB, force=True)
     assert recA.get_property("propA").value == "something else"
@@ -540,9 +539,8 @@ def test_force_merge():
     rtB = db.RecordType()
     rtB.add_property(name="propA", datatype=db.TEXT)
 
-    with pytest.raises(RuntimeError) as re:
+    with pytest.raises(EntityMergeConflictError):
         merge_entities(rtA, rtB)
-    assert "Merge conflict" in str(re.value)
 
     merge_entities(rtA, rtB, force=True)
     assert rtA.get_property("propA").datatype == db.TEXT
@@ -555,9 +553,8 @@ def test_force_merge():
     recB = db.Record()
     recB.add_property(name="propA", value=5, unit="cm")
 
-    with pytest.raises(RuntimeError) as re:
+    with pytest.raises(EntityMergeConflictError):
         merge_entities(recA, recB)
-    assert "Merge conflict" in str(re.value)
     merge_entities(recA, recB, force=True)
     assert recA.get_property("propA").unit == "cm"
     # unchanged