diff --git a/app/api/network.py b/app/api/network.py
index be24d54a53ddfc31e40603245577b65e321cc064..503f575e631b3e35ce2f2a4eb29ebfc0131ffe39 100644
--- a/app/api/network.py
+++ b/app/api/network.py
@@ -326,6 +326,8 @@ def get_hosts():
             query.join(models.Host.interfaces)
             .join(models.Interface.network)
             .filter(models.Network.sensitive.is_(False))
+            .distinct(models.Host.id)
+            .from_self()
         )
     query = query.order_by(models.Host.name)
     return utils.get_generic_model(model=models.Host, base_query=query)
diff --git a/tests/functional/test_api.py b/tests/functional/test_api.py
index 719e33ec3dcf7a69276a4af8f7640a41d45926d9..c89617f873b09d8d7ef1c25fabc1d3f4bc7d31b5 100644
--- a/tests/functional/test_api.py
+++ b/tests/functional/test_api.py
@@ -10,6 +10,7 @@ This module defines API tests.
 
 """
 import datetime
+import ipaddress
 import json
 import pytest
 from app import models
@@ -146,6 +147,28 @@ def get_token(client, username, password):
     return response.get_json()["access_token"]
 
 
+def create_hosts(number, host_factory, interface_factory, *args):
+    """Helper function to create a number of hosts
+
+    :param number: number of hosts to create
+    :param host_factory: host_factory fixture
+    :param interface_factory: interface_factory fixture
+    :param *args: list of networks (host will have one interface per network)
+    """
+    for i in range(number):
+        host = host_factory()
+        for n, network in enumerate(args):
+            ip = ipaddress.ip_address(network.first_ip) + i
+            if n == 0:
+                interface_factory(
+                    name=host.name, host=host, network=network, ip=str(ip)
+                )
+            else:
+                interface_factory(
+                    name=f"{host.name}-{n}", host=host, network=network, ip=str(ip)
+                )
+
+
 @pytest.fixture()
 def readonly_token(client):
     return get_token(client, "user_ro", "userro")
@@ -2050,6 +2073,111 @@ def test_pagination(endpoint, client, host_factory, admin_token):
     )
 
 
+def test_get_hosts_normal_user(
+    client,
+    network_scope_factory,
+    network_factory,
+    interface_factory,
+    host_factory,
+    user_token,
+):
+    # Create several networks
+    scope = network_scope_factory(name="FooNetworks", supernet="192.168.0.0/16")
+    admin_network = network_factory(
+        vlan_name="admin-network",
+        address="192.168.1.0/24",
+        first_ip="192.168.1.10",
+        last_ip="192.168.1.250",
+        admin_only=True,
+        scope=scope,
+    )
+    sensitive_network = network_factory(
+        vlan_name="sensitive-network",
+        address="192.168.2.0/24",
+        first_ip="192.168.2.10",
+        last_ip="192.168.2.250",
+        admin_only=True,
+        sensitive=True,
+        scope=scope,
+    )
+    user1_network = network_factory(
+        vlan_name="user1-network",
+        address="192.168.3.0/24",
+        first_ip="192.168.3.10",
+        last_ip="192.168.3.250",
+        scope=scope,
+    )
+    user2_network = network_factory(
+        vlan_name="user2-network",
+        address="192.168.4.0/24",
+        first_ip="192.168.4.10",
+        last_ip="192.168.4.250",
+        scope=scope,
+    )
+    user3_network = network_factory(
+        vlan_name="user3-network",
+        address="192.168.5.0/24",
+        first_ip="192.168.5.10",
+        last_ip="192.168.5.250",
+        scope=scope,
+    )
+    # Create 15 hosts on admin network
+    create_hosts(15, host_factory, interface_factory, admin_network)
+    # Create 10 hosts on sensitive network (should be filtered out)
+    create_hosts(10, host_factory, interface_factory, sensitive_network)
+    # Create 20 hosts on user1 network
+    create_hosts(20, host_factory, interface_factory, user1_network)
+    # Create 10 hosts on user2 and user3 networks
+    # Hosts with several interfaces required to reproduce INFRA-1888
+    create_hosts(10, host_factory, interface_factory, user2_network, user3_network)
+    # Create 8 more hosts without interfaces (should be filtered out)
+    create_hosts(8, host_factory, interface_factory)
+    url = f"{API_URL}/network/hosts"
+    # By default 20 hosts per page shall be returned
+    response = get(client, url, token=user_token)
+    assert response.status_code == 200
+    assert len(response.get_json()) == 20
+    assert response.headers["x-total-count"] == "45"
+    assert (
+        f'{url}?per_page=20&page=2&recursive=False>; rel="next",'
+        in response.headers["link"]
+    )
+    # Get second page
+    response = get(
+        client, f"{url}?per_page=20&page=2&recursive=False", token=user_token,
+    )
+    assert response.status_code == 200
+    assert len(response.get_json()) == 20
+    assert (
+        f'{url}?per_page=20&page=1&recursive=False>; rel="first",'
+        in response.headers["link"]
+    )
+    assert (
+        f'{url}?per_page=20&page=1&recursive=False>; rel="prev"'
+        in response.headers["link"]
+    )
+    assert (
+        f'{url}?per_page=20&page=3&recursive=False>; rel="next",'
+        in response.headers["link"]
+    )
+    assert (
+        f'{url}?per_page=20&page=3&recursive=False>; rel="last"'
+        in response.headers["link"]
+    )
+    # Get third page
+    response = get(
+        client, f"{url}?per_page=20&page=3&recursive=False", token=user_token,
+    )
+    assert response.status_code == 200
+    assert len(response.get_json()) == 5
+    assert (
+        f'{url}?per_page=20&page=2&recursive=False>; rel="prev"'
+        in response.headers["link"]
+    )
+    assert 'rel="next"' not in response.headers["link"]
+    assert 'rel="last"' not in response.headers["link"]
+
+
 def test_patch_host_no_data(client, host_factory, admin_token):
     host = host_factory()
     response = patch(