diff --git a/api/funkwhale_api/common/utils.py b/api/funkwhale_api/common/utils.py
index 57bcba932f89008be946ea62e429659c45a12426..7763e9b7f810090018fb9845a7fb390df812c0d9 100644
--- a/api/funkwhale_api/common/utils.py
+++ b/api/funkwhale_api/common/utils.py
@@ -113,6 +113,9 @@ def chunk_queryset(source_qs, chunk_size):
 
 
 def join_url(start, end):
+    if end.startswith("http://") or end.startswith("https://"):
+        # alread a full URL, joining makes no sense
+        return end
     if start.endswith("/") and end.startswith("/"):
         return start + end[1:]
 
diff --git a/api/tests/common/test_utils.py b/api/tests/common/test_utils.py
index ea64ed9d2834f8d97aee7425fb223548ffab1b52..74a3d0bca61526e1cf7b5e87772a18a17a3a77aa 100644
--- a/api/tests/common/test_utils.py
+++ b/api/tests/common/test_utils.py
@@ -85,3 +85,17 @@ def test_get_updated_fields(conf, mock_args, data, expected, mocker):
     obj = mocker.Mock(**mock_args)
 
     assert utils.get_updated_fields(conf, data, obj) == expected
+
+
+@pytest.mark.parametrize(
+    "start, end, expected",
+    [
+        ("https://domain", "/api", "https://domain/api"),
+        ("https://domain/", "/api", "https://domain/api"),
+        ("https://domain", "api", "https://domain/api"),
+        ("https://domain", "https://api", "https://api"),
+        ("https://domain", "http://api", "http://api"),
+    ],
+)
+def test_join_url(start, end, expected):
+    assert utils.join_url(start, end) == expected
diff --git a/changes/changelog.d/851.bugfix b/changes/changelog.d/851.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..e6866b3e1f99b5c47ff6d764394da4ef501e1a7c
--- /dev/null
+++ b/changes/changelog.d/851.bugfix
@@ -0,0 +1 @@
+Fixed wrong og:image url when using S3 storage (#851)