diff --git a/Fatras/CMakeLists.txt b/Fatras/CMakeLists.txt
index 1390603518bc373a8467524aa28526936f842411..5795fda862b928783b1effc7f16f8238b947e042 100644
--- a/Fatras/CMakeLists.txt
+++ b/Fatras/CMakeLists.txt
@@ -4,6 +4,7 @@ add_library(
   src/Particle.cpp
   src/ParticleData.cpp
   src/ProcessType.cpp
+  src/SimulatorError.cpp
   src/StandardPhysicsLists.cpp)
 target_compile_features(
   ActsFatras
diff --git a/Fatras/include/ActsFatras/Kernel/Simulator.hpp b/Fatras/include/ActsFatras/Kernel/Simulator.hpp
index 98e28cd5eb475c71927464adcfabac655e8e2be5..bee4d7e833483d3c9fe76b874dbaeb6b1b157f0d 100644
--- a/Fatras/include/ActsFatras/Kernel/Simulator.hpp
+++ b/Fatras/include/ActsFatras/Kernel/Simulator.hpp
@@ -28,6 +28,7 @@
 #include "ActsFatras/EventData/Hit.hpp"
 #include "ActsFatras/EventData/Particle.hpp"
 #include "ActsFatras/Kernel/Interactor.hpp"
+#include "ActsFatras/Kernel/detail/SimulatorError.hpp"
 
 namespace ActsFatras {
 
@@ -209,8 +210,7 @@ struct Simulator {
       // required to allow correct particle id numbering for secondaries later
       if ((inputParticle.particleId().generation() != 0u) or
           (inputParticle.particleId().subParticle() != 0u)) {
-        // TODO add meaningfull error code
-        return std::error_code(-1, std::generic_category());
+        return detail::SimulatorError::eInvalidInputParticleId;
       }
 
       // Do a *depth-first* simulation of the particle and its secondaries,
diff --git a/Fatras/include/ActsFatras/Kernel/detail/SimulatorError.hpp b/Fatras/include/ActsFatras/Kernel/detail/SimulatorError.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6cf816d105bdcba69646dc1cf9a526f9f0634712
--- /dev/null
+++ b/Fatras/include/ActsFatras/Kernel/detail/SimulatorError.hpp
@@ -0,0 +1,34 @@
+// This file is part of the Acts project.
+//
+// Copyright (C) 2020 CERN for the benefit of the Acts project
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+#include <system_error>
+
+namespace ActsFatras {
+namespace detail {
+
+enum class SimulatorError {
+  // ensure all errors are non-null
+  eInvalidInputParticleId = 1,
+};
+
+/// Construct and error_code from the enum.
+///
+/// Must use snake_case naming for STL compatibility.
+std::error_code make_error_code(SimulatorError e);
+
+}  // namespace detail
+}  // namespace ActsFatras
+
+// Register the error enum as STL-compatible.
+namespace std {
+template <>
+struct is_error_code_enum<ActsFatras::detail::SimulatorError> : std::true_type {
+};
+}  // namespace std
diff --git a/Fatras/src/SimulatorError.cpp b/Fatras/src/SimulatorError.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7970b7acd233ca70c489b36bb75cb9035dae46e8
--- /dev/null
+++ b/Fatras/src/SimulatorError.cpp
@@ -0,0 +1,38 @@
+// This file is part of the Acts project.
+//
+// Copyright (C) 2020 CERN for the benefit of the Acts project
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include "ActsFatras/Kernel/detail/SimulatorError.hpp"
+
+namespace ActsFatras {
+namespace detail {
+namespace {
+
+// Define a custom error code category derived from std::error_category
+class SimulatorErrorCategory final : public std::error_category {
+ public:
+  const char* name() const noexcept final { return "SimulatorError"; }
+  std::string message(int c) const final {
+    switch (static_cast<SimulatorError>(c)) {
+      case SimulatorError::eInvalidInputParticleId:
+        return "Input particle id with non-zero generation or sub-particle";
+      default:
+        return "unknown";
+    }
+  }
+};
+
+const SimulatorErrorCategory s_simulatorErrorCategory;
+
+}  // namespace
+
+std::error_code make_error_code(SimulatorError e) {
+  return {static_cast<int>(e), s_simulatorErrorCategory};
+}
+
+}  // namespace detail
+}  // namespace ActsFatras