diff --git a/gso/schedules/validate_subscriptions.py b/gso/schedules/validate_subscriptions.py
index 4a68b6f00810cd9f2c8f46ef811068b7534af3d9..2e55b05e02e74862c29616e3df9b202f6c31e464 100644
--- a/gso/schedules/validate_subscriptions.py
+++ b/gso/schedules/validate_subscriptions.py
@@ -2,7 +2,7 @@
 
 import structlog
 from orchestrator.services.processes import get_execution_context
-from orchestrator.services.subscriptions import TARGET_DEFAULT_USABLE_MAP, WF_USABLE_MAP
+from orchestrator.services.subscriptions import TARGET_DEFAULT_USABLE_MAP
 from orchestrator.targets import Target
 
 from gso.schedules.scheduling import CronScheduleConfig, scheduler
@@ -29,8 +29,10 @@ def validate_subscriptions() -> None:
                 validation_workflow = workflow.name
 
         if validation_workflow:
-            default = TARGET_DEFAULT_USABLE_MAP[Target.SYSTEM]
-            usable_when = WF_USABLE_MAP.get(validation_workflow, default)
+            #  Validation workflows only run on subscriptions that are active, even when they could be run on
+            #  provisioning subscriptions. E.g. for routers, they can manually be validated when provisioning, but are
+            #  not included in this schedule.
+            usable_when = TARGET_DEFAULT_USABLE_MAP[Target.SYSTEM]
 
             if subscription.status in usable_when:
                 json = [{"subscription_id": str(subscription.subscription_id)}]
diff --git a/gso/workflows/__init__.py b/gso/workflows/__init__.py
index 96638b85b66ca805f1f01d32053f65724d66f807..f6a36f9b773e8660973a5c349ad6a881fc1e74fa 100644
--- a/gso/workflows/__init__.py
+++ b/gso/workflows/__init__.py
@@ -21,6 +21,7 @@ WF_USABLE_MAP.update({
     "terminate_router": ALL_ALIVE_STATES,
     "terminate_iptrunk": ALL_ALIVE_STATES,
     "promote_p_to_pe": [SubscriptionLifecycle.ACTIVE],
+    "validate_router": [SubscriptionLifecycle.PROVISIONING, SubscriptionLifecycle.ACTIVE],
 })
 
 #  IP trunk workflows
diff --git a/test/workflows/router/test_validate_router.py b/test/workflows/router/test_validate_router.py
index 07fc78d74a8297f6d6b2a5f6d458aa1c6eeb5cab..22e7359a50bef375fd6c5a8f2a20083040faabb9 100644
--- a/test/workflows/router/test_validate_router.py
+++ b/test/workflows/router/test_validate_router.py
@@ -2,6 +2,7 @@ from unittest.mock import patch
 
 import pytest
 from infoblox_client import objects
+from orchestrator.types import SubscriptionLifecycle
 
 from gso.products.product_types.router import Router
 from test.services.conftest import MockedKentikClient
@@ -13,6 +14,7 @@ from test.workflows import (
 )
 
 
+@pytest.mark.parametrize("router_state", [SubscriptionLifecycle.PROVISIONING, SubscriptionLifecycle.ACTIVE])
 @pytest.mark.workflow()
 @patch("gso.services.infoblox.find_host_by_fqdn")
 @patch("gso.services.lso_client._send_request")
@@ -29,11 +31,12 @@ def test_validate_nokia_router_success(
     faker,
     data_config_filename,
     geant_partner,
+    router_state,
 ):
     mock_validate_librenms_device.return_value = None
     mock_kentik_client.return_value = MockedKentikClient
     #  Run workflow
-    subscription_id = nokia_router_subscription_factory()
+    subscription_id = nokia_router_subscription_factory(status=router_state)
     mock_fqdn = Router.from_subscription(subscription_id).router.router_fqdn
     mock_v4 = faker.ipv4()
     mock_find_host_by_fqdn.return_value = objects.HostRecord(
@@ -66,7 +69,7 @@ def test_validate_nokia_router_success(
     state = extract_state(result)
     subscription = Router.from_subscription(subscription_id)
 
-    assert subscription.status == "active"
+    assert subscription.status == router_state
     assert mock_execute_playbook.call_count == 2
     assert mock_find_host_by_fqdn.call_count == 1
     assert mock_get_device_by_name.call_count == 1