diff --git a/Changelog.md b/Changelog.md
index 054362f48eef2633ff73a177a4ac9285c5b9613d..ac852abafd6257877a7c85f5fb8d5d2579fff948 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,5 +1,9 @@
 # Changelog
-## [2.40] - 2025-20-24
+## [2.41] - 2025-02-28
+- Check uniqueness of GS, GA and VC IDs against active subscriptions.
+- `migrate_l3_core_service`: Update in parameters passed to Moodi to target the destination node.
+
+## [2.40] - 2025-02-24
 - Fixes in `migrate_l3_core_service` WF.
 
 ## [2.39] - 2025-02-24
diff --git a/gso/services/subscriptions.py b/gso/services/subscriptions.py
index c09641194beed749866228cbf17d82764b4b7f26..543fae4a1f24def0afbce8b2a5f5f7607dc56ca7 100644
--- a/gso/services/subscriptions.py
+++ b/gso/services/subscriptions.py
@@ -388,7 +388,7 @@ def get_all_active_sites() -> list[dict[str, Any]]:
 
 
 def is_resource_type_value_unique(resource_type: str, value: str) -> bool:
-    """Check if the given value for the specified resource type is unique in the database.
+    """Check if the given value for the specified resource type is unique in the database for active subscriptions.
 
     This function verifies if the specified value for the given resource type is not already in the core database.
 
@@ -400,8 +400,13 @@ def is_resource_type_value_unique(resource_type: str, value: str) -> bool:
     :rtype: bool
     """
     exists = (
-        ResourceTypeTable.query.join(SubscriptionInstanceValueTable)
-        .filter(ResourceTypeTable.resource_type == resource_type, SubscriptionInstanceValueTable.value == value)
+        SubscriptionTable.query.join(ProductTable)
+        .join(SubscriptionInstanceTable)
+        .join(SubscriptionInstanceValueTable)
+        .join(ResourceTypeTable)
+        .filter(SubscriptionInstanceValueTable.value == value)
+        .filter(ResourceTypeTable.resource_type == resource_type)
+        .filter(SubscriptionTable.status == SubscriptionLifecycle.ACTIVE)
         .scalar()
     )
     return exists is None
diff --git a/gso/utils/workflow_steps.py b/gso/utils/workflow_steps.py
index 5d6e54fb384b5f89546dc67020933fbb8a61e6c0..754af0819ae239fa1064c7320dace6572fd62f32 100644
--- a/gso/utils/workflow_steps.py
+++ b/gso/utils/workflow_steps.py
@@ -408,11 +408,11 @@ def start_moodi() -> StepList:
     host = load_oss_params().MOODI.host
 
     @step("Start Moodi")
-    def _start_moodi(subscription: dict[str, Any]) -> LSOState:
+    def _start_moodi(state: State) -> LSOState:
         return {
             "playbook_name": "moodi_telemetry/playbooks/start_moodi.yaml",
             "inventory": {"all": {"hosts": {host: None}}},
-            "extra_vars": {"subscription": subscription},
+            "extra_vars": {"subscription": state.get("scoped_subscription", state.get("subscription"))},
         }
 
     return _is_moodi_enabled(indifferent_lso_interaction(_start_moodi))
diff --git a/gso/workflows/l3_core_service/migrate_l3_core_service.py b/gso/workflows/l3_core_service/migrate_l3_core_service.py
index 619d438b17e9aabae0c003ca8c578928b284dde6..3f97983c5d72ffff255257cc735bd800d3e09785 100644
--- a/gso/workflows/l3_core_service/migrate_l3_core_service.py
+++ b/gso/workflows/l3_core_service/migrate_l3_core_service.py
@@ -405,8 +405,8 @@ def migrate_l3_core_service() -> StepList:
         >> is_human_initiated_wf(lso_interaction(deactivate_sbp_real))
         >> is_human_initiated_wf(inform_operator_traffic_check)
         >> unsync
-        >> start_moodi()  # TODO: include results from first LSO run
         >> generate_scoped_subscription_model
+        >> start_moodi()  # TODO: include results from first LSO run
         >> lso_interaction(deploy_destination_ep_dry)
         >> lso_interaction(deploy_destination_ep_real)
         >> lso_interaction(deploy_bgp_session_dry)
diff --git a/setup.py b/setup.py
index dc9368d9b1a7f5d3bc9dd78fa298b444085c6cbf..6815cae22a25215df58cf854c2861bf975d504e1 100644
--- a/setup.py
+++ b/setup.py
@@ -4,7 +4,7 @@ from setuptools import find_packages, setup
 
 setup(
     name="geant-service-orchestrator",
-    version="2.40",
+    version="2.41",
     author="GÉANT Orchestration and Automation Team",
     author_email="goat@geant.org",
     description="GÉANT Service Orchestrator",
diff --git a/test/conftest.py b/test/conftest.py
index 38fa426f64bd4365511221b3c679ff6c1cd31181..731e0a3c1894d10f73a29cbbc4f6c79ec045108a 100644
--- a/test/conftest.py
+++ b/test/conftest.py
@@ -33,6 +33,7 @@ from starlette.testclient import TestClient
 from urllib3_mock import Responses
 
 from gso.services.partners import PartnerSchema, create_partner
+from gso.services.subscriptions import is_resource_type_value_unique
 from gso.utils.types.interfaces import LAGMember, LAGMemberList
 from test.fixtures import *  # noqa: F403
 
@@ -83,21 +84,25 @@ class FakerProvider(BaseProvider):
 
         return f"TT#{random_date}{random_int}"
 
+    def generate_unique_id(self, field_name: str, prefix: str, min_value: int = 50000, max_value: int = 99999) -> str:
+        """Generate a unique ID with a given prefix and ensure uniqueness in the database."""
+        while True:
+            random_int = self.generator.random_int(min=min_value, max=max_value)
+            unique_id = f"{prefix}-{random_int}"
+            if is_resource_type_value_unique(field_name, unique_id):
+                return unique_id
+
     def ga_id(self) -> str:
-        random_int = self.generator.random_int(min=50000, max=99999)
-        return f"GA-{random_int}"
+        return self.generate_unique_id("ga_id", "GA")
 
     def gs_id(self) -> str:
-        random_int = self.generator.random_int(min=50000, max=99999)
-        return f"GS-{random_int}"
+        return self.generate_unique_id("gs_id", "GS")
 
     def imported_ga_id(self) -> str:
-        random_int = self.generator.random_int(min=00000, max=50000)
-        return f"GA-{random_int}"
+        return self.generate_unique_id("ga_id", "GA", min_value=00000, max_value=50000)
 
     def imported_gs_id(self) -> str:
-        random_int = self.generator.random_int(min=00000, max=50000)
-        return f"GS-{random_int}"
+        return self.generate_unique_id("gs_id", "GS", min_value=00000, max_value=50000)
 
     def site_name(self) -> str:
         site_name = "".join(self.generator.random_letter().upper() for _ in range(3))
diff --git a/test/workflows/edge_port/test_create_edge_port.py b/test/workflows/edge_port/test_create_edge_port.py
index 145dbbc092b4ecce7d42a0dadd68e2b128bf3264..941995bcd0693ec945da844f2052402eaf8cba75 100644
--- a/test/workflows/edge_port/test_create_edge_port.py
+++ b/test/workflows/edge_port/test_create_edge_port.py
@@ -1,6 +1,8 @@
 from unittest.mock import patch
 
 import pytest
+from orchestrator.db import db
+from orchestrator.types import SubscriptionLifecycle
 from pydantic_forms.exceptions import FormValidationError
 
 from gso.products import ProductName
@@ -159,3 +161,46 @@ def test_edge_port_creation_with_invalid_input(
     error = error.value.errors[0]
     assert error["msg"] == "Number of members must be 1 if LACP is disabled."
     assert error["loc"][0] == "__root__"
+
+
+@pytest.mark.workflow()
+@patch("gso.services.lso_client._send_request")
+def test_edge_port_creation_with_existing_ga_id(
+    mock_execute_playbook,
+    input_form_wizard_data,
+    faker,
+    _netbox_client_mock,  # noqa: PT019
+    test_client,
+    edge_port_subscription_factory,
+):
+    subscription = edge_port_subscription_factory(ga_id="GA-12345")
+    product_id = get_product_id_by_name(ProductName.EDGE_PORT)
+    initial_data = [{"product": product_id}, *input_form_wizard_data]
+    with pytest.raises(FormValidationError) as error:
+        run_workflow("create_edge_port", initial_data)
+
+    error = error.value.errors[0]
+    assert error["msg"] == "ga_id must be unique, GA-12345 is already in use."
+    assert error["loc"][0] == "ga_id"
+
+    # Terminate the subscription and check if the workflow can be run successfully
+    subscription = EdgePort.from_subscription(subscription.subscription_id)
+    subscription.status = SubscriptionLifecycle.TERMINATED
+    subscription.save()
+    db.session.commit()
+
+    result, process_stat, step_log = run_workflow("create_edge_port", initial_data)
+
+    for _ in range(3):
+        result, step_log = assert_lso_interaction_success(result, process_stat, step_log)
+
+    result, step_log = assert_stop_moodi(result, process_stat, step_log)
+
+    assert_complete(result)
+
+    state = extract_state(result)
+    subscription_id = state["subscription_id"]
+    subscription = EdgePort.from_subscription(subscription_id)
+
+    assert subscription.status == "active"
+    assert subscription.edge_port.ga_id.startswith("GA-12345")