diff --git a/api/funkwhale_api/federation/activity.py b/api/funkwhale_api/federation/activity.py
index fd397fe18f11fc63b97fb9b242b9ec25c1e5e49d..4141da795d7bbdcd60308664004a6436450bd3d2 100644
--- a/api/funkwhale_api/federation/activity.py
+++ b/api/funkwhale_api/federation/activity.py
@@ -121,6 +121,7 @@ def receive(activity, on_behalf_of):
     from . import models
     from . import serializers
     from . import tasks
+    from .routes import inbox
 
     # we ensure the activity has the bare minimum structure before storing
     # it in our database
@@ -128,6 +129,10 @@ def receive(activity, on_behalf_of):
         data=activity, context={"actor": on_behalf_of, "local_recipients": True}
     )
     serializer.is_valid(raise_exception=True)
+    if not inbox.get_matching_handlers(activity):
+        # discard unhandlable activity
+        return
+
     if should_reject(
         fid=serializer.validated_data.get("id"),
         actor_id=serializer.validated_data["actor"].fid,
diff --git a/api/tests/federation/test_activity.py b/api/tests/federation/test_activity.py
index 15b06316739da7625b3382c3aedfaeb2741ea593..e195a758721a3e42e5fb5b9418f2217a6ecebf56 100644
--- a/api/tests/federation/test_activity.py
+++ b/api/tests/federation/test_activity.py
@@ -14,6 +14,9 @@ from funkwhale_api.federation import (
 
 
 def test_receive_validates_basic_attributes_and_stores_activity(factories, now, mocker):
+    mocker.patch.object(
+        activity.InboxRouter, "get_matching_handlers", return_value=True
+    )
     mocked_dispatch = mocker.patch("funkwhale_api.common.utils.on_commit")
     local_to_actor = factories["users.User"]().create_actor()
     local_cc_actor = factories["users.User"]().create_actor()
@@ -48,6 +51,9 @@ def test_receive_validates_basic_attributes_and_stores_activity(factories, now,
 
 def test_receive_calls_should_reject(factories, now, mocker):
     should_reject = mocker.patch.object(activity, "should_reject", return_value=True)
+    mocker.patch.object(
+        activity.InboxRouter, "get_matching_handlers", return_value=True
+    )
     local_to_actor = factories["users.User"]().create_actor()
     remote_actor = factories["federation.Actor"]()
     a = {
@@ -65,6 +71,26 @@ def test_receive_calls_should_reject(factories, now, mocker):
     assert copy is None
 
 
+def test_receive_skips_if_no_matching_route(factories, now, mocker):
+    get_matching_handlers = mocker.patch.object(
+        activity.InboxRouter, "get_matching_handlers", return_value=[]
+    )
+    local_to_actor = factories["users.User"]().create_actor()
+    remote_actor = factories["federation.Actor"]()
+    a = {
+        "@context": [],
+        "actor": remote_actor.fid,
+        "type": "Noop",
+        "id": "https://test.activity",
+        "to": [local_to_actor.fid, remote_actor.fid],
+    }
+
+    copy = activity.receive(activity=a, on_behalf_of=remote_actor)
+    get_matching_handlers.assert_called_once_with(a)
+    assert copy is None
+    assert models.Activity.objects.count() == 0
+
+
 @pytest.mark.parametrize(
     "params, policy_kwargs, expected",
     [
diff --git a/changes/changelog.d/776.enhancement b/changes/changelog.d/776.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..4cdf48815ade07870fb1e29ca05c5df836078d07
--- /dev/null
+++ b/changes/changelog.d/776.enhancement
@@ -0,0 +1 @@
+Don't store unhandled ActivityPub messages in database (#776)