diff --git a/test/integration/Elsa.Activities.IntegrationTests/Primitives/FaultTests.cs b/test/integration/Elsa.Activities.IntegrationTests/Primitives/FaultTests.cs
new file mode 100644
index 000000000..46d18ceeb
--- /dev/null
+++ b/test/integration/Elsa.Activities.IntegrationTests/Primitives/FaultTests.cs
@@ -0,0 +1,84 @@
+using Elsa.Activities.IntegrationTests.Primitives.Workflows;
+using Elsa.Testing.Shared;
+using Elsa.Workflows;
+using Elsa.Workflows.Activities;
+using Elsa.Workflows.Exceptions;
+using Elsa.Workflows.Models;
+using Elsa.Workflows.State;
+using Xunit.Abstractions;
+
+namespace Elsa.Activities.IntegrationTests.Primitives;
+
+///
+/// Integration tests for the activity.
+///
+public class FaultTests(ITestOutputHelper testOutputHelper)
+{
+ private readonly WorkflowTestFixture _fixture = new WorkflowTestFixture(testOutputHelper)
+ .AddWorkflow()
+ .AddWorkflow()
+ .AddWorkflow()
+ .AddWorkflow();
+
+ [Fact(DisplayName = "Fault activity faults workflow execution")]
+ public async Task Fault_Activity_Faults_Workflow_Execution()
+ {
+ // Act
+ var workflowState = await _fixture.RunWorkflowAsync(FaultWorkflow.DefinitionId);
+
+ // Assert
+ AssertWorkflowFaulted(workflowState);
+ var incident = GetSingleIncident(workflowState);
+ Assert.Equal("Test fault message", incident.Message);
+ }
+
+ [Fact(DisplayName = "Fault activity with default values faults workflow")]
+ public async Task Fault_With_Default_Values_Faults_Workflow()
+ {
+ // Act
+ var workflowState = await _fixture.RunWorkflowAsync(FaultWithDefaultsWorkflow.DefinitionId);
+
+ // Assert
+ AssertWorkflowFaulted(workflowState);
+ GetSingleIncident(workflowState);
+ }
+
+ [Fact(DisplayName = "Fault in sequence stops subsequent activities")]
+ public async Task Fault_In_Sequence_Stops_Subsequent_Activities()
+ {
+ // Act
+ var workflowState = await _fixture.RunWorkflowAsync(FaultInSequenceWorkflow.DefinitionId);
+
+ // Assert
+ AssertWorkflowFaulted(workflowState);
+
+ var lines = _fixture.CapturingTextWriter.Lines.ToList();
+ Assert.Contains("Before fault", lines);
+ Assert.DoesNotContain("After fault - should not execute", lines);
+ }
+
+ [Fact(DisplayName = "Fault with factory method creates correct exception")]
+ public async Task Fault_Created_With_Factory_Method()
+ {
+ // Act
+ var workflowState = await _fixture.RunWorkflowAsync(FaultViaFactoryWorkflow.DefinitionId);
+
+ // Assert
+ AssertWorkflowFaulted(workflowState);
+ var incident = GetSingleIncident(workflowState);
+ Assert.Equal("Created via factory", incident.Message);
+ }
+
+ private static void AssertWorkflowFaulted(WorkflowState workflowState)
+ {
+ Assert.Equal(WorkflowSubStatus.Faulted, workflowState.SubStatus);
+ }
+
+ private static ActivityIncident GetSingleIncident(WorkflowState workflowState)
+ {
+ var incident = Assert.Single(workflowState.Incidents);
+ Assert.NotNull(incident.Exception);
+ Assert.Equal(typeof(FaultException), incident.Exception.Type);
+ return incident;
+ }
+}
\ No newline at end of file
diff --git a/test/integration/Elsa.Activities.IntegrationTests/Primitives/Workflows/FaultInSequenceWorkflow.cs b/test/integration/Elsa.Activities.IntegrationTests/Primitives/Workflows/FaultInSequenceWorkflow.cs
new file mode 100644
index 000000000..c19f21756
--- /dev/null
+++ b/test/integration/Elsa.Activities.IntegrationTests/Primitives/Workflows/FaultInSequenceWorkflow.cs
@@ -0,0 +1,29 @@
+using Elsa.Workflows;
+using Elsa.Workflows.Activities;
+
+namespace Elsa.Activities.IntegrationTests.Primitives.Workflows;
+
+public class FaultInSequenceWorkflow : WorkflowBase
+{
+ public static readonly string DefinitionId = nameof(FaultInSequenceWorkflow);
+
+ protected override void Build(IWorkflowBuilder workflow)
+ {
+ workflow.DefinitionId = DefinitionId;
+ workflow.Root = new Sequence
+ {
+ Activities =
+ {
+ new WriteLine("Before fault"),
+ new Fault
+ {
+ Code = new("SEQ_001"),
+ Category = new("Sequence"),
+ FaultType = new("Test"),
+ Message = new("Fault in sequence")
+ },
+ new WriteLine("After fault - should not execute")
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/test/integration/Elsa.Activities.IntegrationTests/Primitives/Workflows/FaultViaFactoryWorkflow.cs b/test/integration/Elsa.Activities.IntegrationTests/Primitives/Workflows/FaultViaFactoryWorkflow.cs
new file mode 100644
index 000000000..efe5e0321
--- /dev/null
+++ b/test/integration/Elsa.Activities.IntegrationTests/Primitives/Workflows/FaultViaFactoryWorkflow.cs
@@ -0,0 +1,15 @@
+using Elsa.Workflows;
+using Elsa.Workflows.Activities;
+
+namespace Elsa.Activities.IntegrationTests.Primitives.Workflows;
+
+public class FaultViaFactoryWorkflow : WorkflowBase
+{
+ public static readonly string DefinitionId = nameof(FaultViaFactoryWorkflow);
+
+ protected override void Build(IWorkflowBuilder workflow)
+ {
+ workflow.DefinitionId = DefinitionId;
+ workflow.Root = Fault.Create("FACTORY_001", "Factory", "Integration", "Created via factory");
+ }
+}
\ No newline at end of file
diff --git a/test/integration/Elsa.Activities.IntegrationTests/Primitives/Workflows/FaultWithDefaultsWorkflow.cs b/test/integration/Elsa.Activities.IntegrationTests/Primitives/Workflows/FaultWithDefaultsWorkflow.cs
new file mode 100644
index 000000000..9b7cb618a
--- /dev/null
+++ b/test/integration/Elsa.Activities.IntegrationTests/Primitives/Workflows/FaultWithDefaultsWorkflow.cs
@@ -0,0 +1,21 @@
+using Elsa.Workflows;
+using Elsa.Workflows.Activities;
+
+namespace Elsa.Activities.IntegrationTests.Primitives.Workflows;
+
+public class FaultWithDefaultsWorkflow : WorkflowBase
+{
+ public static readonly string DefinitionId = nameof(FaultWithDefaultsWorkflow);
+
+ protected override void Build(IWorkflowBuilder workflow)
+ {
+ workflow.DefinitionId = DefinitionId;
+ workflow.Root = new Fault
+ {
+ Code = new((string)null!),
+ Category = new((string)null!),
+ FaultType = new((string)null!),
+ Message = new((string?)null)
+ };
+ }
+}
\ No newline at end of file
diff --git a/test/integration/Elsa.Activities.IntegrationTests/Primitives/Workflows/FaultWorkflow.cs b/test/integration/Elsa.Activities.IntegrationTests/Primitives/Workflows/FaultWorkflow.cs
new file mode 100644
index 000000000..32053fab7
--- /dev/null
+++ b/test/integration/Elsa.Activities.IntegrationTests/Primitives/Workflows/FaultWorkflow.cs
@@ -0,0 +1,21 @@
+using Elsa.Workflows;
+using Elsa.Workflows.Activities;
+
+namespace Elsa.Activities.IntegrationTests.Primitives.Workflows;
+
+public class FaultWorkflow : WorkflowBase
+{
+ public static readonly string DefinitionId = nameof(FaultWorkflow);
+
+ protected override void Build(IWorkflowBuilder workflow)
+ {
+ workflow.DefinitionId = DefinitionId;
+ workflow.Root = new Fault
+ {
+ Code = new("ERR_001"),
+ Category = new("Test"),
+ FaultType = new("Business"),
+ Message = new("Test fault message")
+ };
+ }
+}
\ No newline at end of file
diff --git a/test/unit/Elsa.Activities.UnitTests/Primitives/FaultTests.cs b/test/unit/Elsa.Activities.UnitTests/Primitives/FaultTests.cs
new file mode 100644
index 000000000..179b8923b
--- /dev/null
+++ b/test/unit/Elsa.Activities.UnitTests/Primitives/FaultTests.cs
@@ -0,0 +1,128 @@
+using Elsa.Testing.Shared;
+using Elsa.Workflows;
+using Elsa.Workflows.Exceptions;
+
+namespace Elsa.Activities.UnitTests.Primitives;
+
+///
+/// Unit tests for the activity.
+///
+public class FaultTests
+{
+ [Fact(DisplayName = "Fault throws FaultException with all properties set")]
+ public async Task Should_Throw_FaultException_With_All_Properties()
+ {
+ // Arrange
+ var fault = new Fault
+ {
+ Code = new("ERR_001"),
+ Category = new("HTTP"),
+ FaultType = new("Business"),
+ Message = new("Invalid request")
+ };
+
+ // Act & Assert
+ var exception = await ExecuteAndAssertFaultAsync(fault);
+ Assert.Equal("ERR_001", exception.Code);
+ Assert.Equal("HTTP", exception.Category);
+ Assert.Equal("Business", exception.Type);
+ Assert.Equal("Invalid request", exception.Message);
+ }
+
+ [Fact(DisplayName = "Fault uses default values when inputs are null")]
+ public async Task Should_Use_Default_Values_When_Inputs_Are_Null()
+ {
+ // Arrange
+ var fault = new Fault
+ {
+ Code = new((string)null!),
+ Category = new((string)null!),
+ FaultType = new((string)null!),
+ Message = new((string?)null)
+ };
+
+ // Act & Assert
+ var exception = await ExecuteAndAssertFaultAsync(fault);
+ Assert.Equal("0", exception.Code);
+ Assert.Equal("General", exception.Category);
+ Assert.Equal("System", exception.Type);
+ Assert.NotNull(exception.Message);
+ }
+
+ [Fact(DisplayName = "Fault throws FaultException with null message")]
+ public async Task Should_Throw_FaultException_With_Null_Message()
+ {
+ // Arrange
+ var fault = new Fault
+ {
+ Code = new("ERR_002"),
+ Category = new("Database"),
+ FaultType = new("Integration"),
+ Message = new((string?)null)
+ };
+
+ // Act & Assert
+ var exception = await ExecuteAndAssertFaultAsync(fault);
+ Assert.Equal("ERR_002", exception.Code);
+ Assert.Equal("Database", exception.Category);
+ Assert.Equal("Integration", exception.Type);
+ Assert.NotNull(exception.Message);
+ }
+
+ [Theory(DisplayName = "Fault throws FaultException with various code values")]
+ [InlineData("404", "404")]
+ [InlineData("VALIDATION_ERROR", "VALIDATION_ERROR")]
+ [InlineData("", "")]
+ public async Task Should_Throw_FaultException_With_Various_Codes(string code, string expectedCode)
+ {
+ // Arrange
+ var fault = new Fault
+ {
+ Code = new(code),
+ Category = new("Test"),
+ FaultType = new("Test")
+ };
+
+ // Act & Assert
+ var exception = await ExecuteAndAssertFaultAsync(fault);
+ Assert.Equal(expectedCode, exception.Code);
+ }
+
+ [Fact(DisplayName = "Fault.Create factory method creates correctly configured instance")]
+ public async Task Create_Factory_Method_Creates_Correctly_Configured_Instance()
+ {
+ // Arrange
+ var fault = Fault.Create("CREATE_001", "Factory", "Test", "Created via factory");
+
+ // Act & Assert
+ var exception = await ExecuteAndAssertFaultAsync(fault);
+ Assert.Equal("CREATE_001", exception.Code);
+ Assert.Equal("Factory", exception.Category);
+ Assert.Equal("Test", exception.Type);
+ Assert.Equal("Created via factory", exception.Message);
+ }
+
+ [Fact(DisplayName = "Fault.Create factory method with null message")]
+ public async Task Create_Factory_Method_With_Null_Message()
+ {
+ // Arrange
+ var fault = Fault.Create("CODE", "Category", "Type");
+
+ // Act & Assert
+ var exception = await ExecuteAndAssertFaultAsync(fault);
+ Assert.Equal("CODE", exception.Code);
+ Assert.Equal("Category", exception.Category);
+ Assert.Equal("Type", exception.Type);
+ Assert.NotNull(exception.Message);
+ }
+
+ private static async Task ExecuteAndAssertFaultAsync(IActivity activity)
+ {
+ return await Assert.ThrowsAsync(() => ExecuteAsync(activity));
+ }
+
+ private static async Task ExecuteAsync(IActivity activity)
+ {
+ return await new ActivityTestFixture(activity).ExecuteAsync();
+ }
+}