diff --git a/arkindex/process/serializers/imports.py b/arkindex/process/serializers/imports.py
index a20e77595dff247d19de07d776f09d57f6c152ca..d57533f69d7938302a028ff63ce58612b0e8b15d 100644
--- a/arkindex/process/serializers/imports.py
+++ b/arkindex/process/serializers/imports.py
@@ -319,9 +319,20 @@ class ApplyProcessTemplateSerializer(ProcessACLMixin, serializers.Serializer):
 
     def validate(self, data):
         template_process = self.context["template"]
-        unavailable = template_process.versions.filter(~Q(state=WorkerVersionState.Available) | Q(docker_image_id=None))
-        if unavailable.exists():
+
+        unavailable_worker_versions = template_process.versions.filter(~Q(state=WorkerVersionState.Available) | Q(docker_image_id=None))
+        if unavailable_worker_versions.exists():
             raise ValidationError(detail='This template contains one or more unavailable worker versions and cannot be applied.')
+
+        unavailable_model_versions = (
+            template_process
+            .worker_runs
+            .exclude(model_version_id=None)
+            .exclude(model_version__state='available')
+        )
+        if unavailable_model_versions.exists():
+            raise ValidationError(detail='This template contains one or more unavailable model versions and cannot be applied.')
+
         return data
 
 
diff --git a/arkindex/process/tests/test_templates.py b/arkindex/process/tests/test_templates.py
index 168fbc9e499d791a8d75f7f7f049b1d45064168e..011ecfd56673753313cf82b62afba516b086c488 100644
--- a/arkindex/process/tests/test_templates.py
+++ b/arkindex/process/tests/test_templates.py
@@ -259,7 +259,7 @@ class TestTemplates(FixtureAPITestCase):
 
     def test_apply_process_template(self):
         self.client.force_login(self.user)
-        with self.assertNumQueries(18):
+        with self.assertNumQueries(19):
             response = self.client.post(
                 reverse('api:apply-process-template', kwargs={'pk': str(self.template.id)}),
                 data=json.dumps({"process_id": str(self.process.id)}),
@@ -293,7 +293,7 @@ class TestTemplates(FixtureAPITestCase):
             parents=[],
         )
         # Apply a template that has two other worker runs
-        with self.assertNumQueries(18):
+        with self.assertNumQueries(19):
             response = self.client.post(
                 reverse('api:apply-process-template', kwargs={'pk': str(self.template.id)}),
                 data=json.dumps({"process_id": str(process.id)}),
@@ -332,6 +332,24 @@ class TestTemplates(FixtureAPITestCase):
         self.process.refresh_from_db()
         self.assertEqual(self.process.template, None)
 
+    def test_apply_process_template_unavailable_model_version(self):
+        self.model_version.state = ModelVersionState.Error
+        self.model_version.save()
+        self.client.force_login(self.user)
+
+        with self.assertNumQueries(16):
+            response = self.client.post(
+                reverse('api:apply-process-template', kwargs={'pk': str(self.template.id)}),
+                data=json.dumps({"process_id": str(self.process.id)}),
+                content_type='application/json',
+            )
+            self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
+
+        self.assertDictEqual(response.json(), {'non_field_errors': ['This template contains one or more unavailable model versions and cannot be applied.']})
+
+        self.process.refresh_from_db()
+        self.assertEqual(self.process.template, None)
+
     def test_list_templates_ignores_configuration_filter(self):
         self.client.force_login(self.user)
         with self.assertNumQueries(7):