diff --git a/algo/ca/TrackingChain.cxx b/algo/ca/TrackingChain.cxx
index 3810670e9f5fa6910491a97d4d2a17067cd3564c..1d481261a1af5143deb8128a969175122fcf94eb 100644
--- a/algo/ca/TrackingChain.cxx
+++ b/algo/ca/TrackingChain.cxx
@@ -13,6 +13,7 @@
 #include "CaHit.h"
 #include "CaInitManager.h"
 #include "CaParameters.h"
+#include "KfSetupBuilder.h"
 #include "ParFiles.h"
 #include "compat/OpenMP.h"
 #include "yaml/Yaml.h"
@@ -66,6 +67,8 @@ void TrackingChain::Init()
   L_(info) << "Tracking Chain: reading geometry from CA parameters file " << GNb << geomCfgFile << CL << '\n';
   L_(info) << "Tracking Chain: reading geometry setup file " << GNb << setupCfgFile << CL << '\n';
   L_(info) << "Tracking Chain: reading parameters from CA main config " << GNb << mainCfgFile << CL << '\n';
+
+  //* InitManager instantiation
   auto manager = InitManager{};
   manager.SetDetectorNames(ca::kDetName);
   manager.SetConfigMain(mainCfgFile);
@@ -73,10 +76,36 @@ void TrackingChain::Init()
     L_(info) << "Tracking Chain: applying user configuration from " << GNb << userCfgFile << CL << '\n';
     manager.SetConfigUser(userCfgFile);
   }
-  manager.ReadParametersObject(geomCfgFile);  // geometry setup
-  manager.ReadInputConfigs();
-  manager.ReadGeometrySetup(setupCfgFile);
+
+  //* Read parameters object from the geomCfgFile to intialize tracking stations
+  {
+    manager.ReadParametersObject(geomCfgFile);  // geometry setup
+    auto paramIn = manager.TakeParameters();
+    manager.ClearSetupInfo();
+
+    //* Read setup
+    auto geoSetup = kf::SetupBuilder::Load<ca::fvec>(setupCfgFile);
+    kf::Target<double> target(geoSetup.GetTarget());
+
+    //* Initialize tracking parameters
+    manager.SetFieldFunction([](const double(&)[3], double(&outB)[3]) {
+      outB[0] = 0.;
+      outB[1] = 0.;
+      outB[2] = 0.;
+    });
+    manager.SetTargetPosition(target.GetX(), target.GetY(), target.GetZ());
+    manager.InitTargetField(2.5 /*cm*/);
+    manager.AddStations(paramIn);  // Initialize stations
+    manager.InitStationLayout();
+    manager.ReadInputConfigs();
+    manager.SetGeometrySetup(geoSetup);
+    manager.DevSetIsParSearchWUsed(false);
+    if (!manager.FormParametersContainer()) {
+      throw std::runtime_error("Initialization of CA parameters failed");
+    }
+  }
   auto parameters = manager.TakeParameters();
+
   L_(info) << "Tracking Chain: parameters object: \n" << parameters.ToString(1) << '\n';
 
   // ------ Used detector subsystem flags
diff --git a/algo/ca/core/pars/CaConfigReader.cxx b/algo/ca/core/pars/CaConfigReader.cxx
index 5df9fc277ea0d55275171c03e252f0b97c74fd01..1c84cc1665f8a38d7d264950070665facc411917 100644
--- a/algo/ca/core/pars/CaConfigReader.cxx
+++ b/algo/ca/core/pars/CaConfigReader.cxx
@@ -33,7 +33,8 @@ ConfigReader::ConfigReader(InitManager* pInitManager, int verbose) : fpInitManag
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-YAML::Node ConfigReader::GetNode(std::function<YAML::Node(YAML::Node)> fn) const
+// TODO: switch to the Yaml library by Felix
+YAML::Node ConfigReader::GetNode(std::function<YAML::Node(YAML::Node)> fn, bool optional) const
 {
   auto node = YAML::Node(YAML::NodeType::Undefined);
   if (fUserConfigNode) {
@@ -42,7 +43,7 @@ YAML::Node ConfigReader::GetNode(std::function<YAML::Node(YAML::Node)> fn) const
   if (!node) {
     node = fn(fMainConfigNode);
   }
-  if (!node) {
+  if (!node && !optional) {
     std::stringstream msg;
     msg << "requested node was not found ";
     if (fUserConfigNode) {
@@ -250,7 +251,10 @@ std::vector<std::set<int>> ConfigReader::ReadInactiveStationMap()
 {
   // Check, if the "skip_stations" branch exists either in the user config or in the main config
   std::string sNodePath = "ca/core/common/inactive_stations";
-  auto node             = this->GetNode([](YAML::Node n) { return n["core"]["common"]["inactive_stations"]; });
+  auto node             = GetNode([](YAML::Node n) { return n["core"]["common"]["inactive_stations"]; }, true);
+  if (!node) {
+    return std::vector<std::set<int>>{};
+  }
 
   // Fill map of inactive stations
   std::vector<std::set<int>> vGeoIdToTrackingStatus(constants::size::MaxNdetectors);
diff --git a/algo/ca/core/pars/CaConfigReader.h b/algo/ca/core/pars/CaConfigReader.h
index 9178f975c14a8d0aec99adf0dd92b94f1048f040..7729c9c36cdbcaab151e578f7e87ad7cf4a62e93 100644
--- a/algo/ca/core/pars/CaConfigReader.h
+++ b/algo/ca/core/pars/CaConfigReader.h
@@ -78,14 +78,15 @@ namespace cbm::algo::ca
     void ReadMisalignmentTolerance();
 
     /// \brief Accesses a node either from user config or from main config
-    /// \param fn  A function, which returns a YAML::Node reference object
+    /// \param fn        A function, which returns a YAML::Node reference object
+    /// \param optional  true: node is not mandatory
     /// \note      If the node is not found in both configs
     /// \throw     std::runtime_error, if the path does not exist in the config
     ///
     /// This function is to be used, if the desired node should exist either in main or in user config. Firstly,
     /// the user config is checked, if it is provided. If the node is not found in user config, the main config
     /// is checked. If the node does not exist in the main config as well, an exception will be thrown.
-    YAML::Node GetNode(std::function<YAML::Node(YAML::Node)> fn) const;
+    YAML::Node GetNode(std::function<YAML::Node(YAML::Node)> fn, bool optional = false) const;
 
     /// \brief Reads iteration from config file
     /// \param node         YAML node containing an iteration
diff --git a/algo/ca/core/pars/CaInitManager.cxx b/algo/ca/core/pars/CaInitManager.cxx
index 4bdf43f9e60f21534d6d14f74703eb59f9f11ca4..744709404d42e06ec724cd43bd5ce36dccec40ea 100644
--- a/algo/ca/core/pars/CaInitManager.cxx
+++ b/algo/ca/core/pars/CaInitManager.cxx
@@ -26,6 +26,29 @@ namespace cbm::algo::ca
   //
   void InitManager::AddStation(const StationInitializer& inStation) { fvStationInfo.push_back(inStation); }
 
+  // --------------------------------------------------------------------------------------------------------------------
+  //
+  void InitManager::AddStations(const Parameters<fvec>& par)
+  {
+    const auto& stations = par.GetStations();
+    for (int iSt = 0; iSt < par.GetNstationsActive(); ++iSt) {
+      auto stationIn = Station<double>(stations[iSt]);
+      // Get detector ID of the station
+      auto [detId, locId] = par.GetStationIndexLocal(par.GetActiveToGeoMap()[iSt]);
+      auto stationInfo    = ca::StationInitializer(detId, locId);
+      stationInfo.SetStationType(stationIn.type);
+      stationInfo.SetZmin(0.);  // NOTE: Deprecated (not used)
+      stationInfo.SetZmax(0.);  // NOTE: Deprecated (not used)
+      stationInfo.SetZref(stationIn.fZ);
+      stationInfo.SetXmax(stationIn.Xmax);
+      stationInfo.SetYmax(stationIn.Ymax);
+      stationInfo.SetFieldStatus(stationIn.fieldStatus);
+      stationInfo.SetTimeInfo(stationIn.timeInfo);
+      stationInfo.SetTrackingStatus(true);
+      this->AddStation(stationInfo);
+    }
+  }
+
   // --------------------------------------------------------------------------------------------------------------------
   //
   void InitManager::CheckInit()
@@ -78,6 +101,8 @@ namespace cbm::algo::ca
     fParameters.fDevIsExtendTracksViaMc        = false;
     fParameters.fDevIsSuppressOverlapHitsViaMc = false;
     fParameters.fDevIsParSearchWUsed           = false;
+
+    fbGeometryConfigLock = false;
   }
 
   // --------------------------------------------------------------------------------------------------------------------
diff --git a/algo/ca/core/pars/CaInitManager.h b/algo/ca/core/pars/CaInitManager.h
index b1dc5118f102aae2d8682a4b5aca126ec619fd54..4e00f2658610751d7126ef79d84ad53641e07e28 100644
--- a/algo/ca/core/pars/CaInitManager.h
+++ b/algo/ca/core/pars/CaInitManager.h
@@ -105,6 +105,16 @@ namespace cbm::algo::ca
     /// \note The added station stays uninitialized until the Parameters object is formed
     void AddStation(const StationInitializer& station);
 
+    /// \brief Adds tracking stations from the parameters file
+    /// \param par  A valid instance of parameters, created for ACTIVE + INACTIVE tracking stations
+    ///
+    // TODO: Probably, we have to remove stations from the parameters and place them into a class ca::Geometery
+    //       together with instances of active and geometry kf::Setup. ca::Parameters should contain only tracking
+    //       parameters, which should be fully defined from the config. Search windows should be stored as an
+    //       independent object, which depends on the ca::Parameters(iterations) and ca::Geometry(active station
+    //       layout).
+    void AddStations(const Parameters<fvec>& par);
+
     /// \brief Provides final checks of the parameters object
     void CheckInit();
 
diff --git a/reco/L1/qa/CbmCaInputQaSetup.cxx b/reco/L1/qa/CbmCaInputQaSetup.cxx
index ceaa683a71ac973088571ec00f2dd0b56a745b70..3b1489087a3636b92b04ff597d77ecc9de84da1a 100644
--- a/reco/L1/qa/CbmCaInputQaSetup.cxx
+++ b/reco/L1/qa/CbmCaInputQaSetup.cxx
@@ -12,8 +12,8 @@
 #include "CbmCaParametersHandler.h"
 #include "CbmL1DetectorID.h"
 #include "CbmMCDataManager.h"
-#include "FairRootManager.h"
 #include "CbmSetup.h"
+#include "FairRootManager.h"
 #include "TAxis.h"
 
 #include <Logger.h>
@@ -54,7 +54,7 @@ void InputQaSetup::CheckInit() const
 //
 void InputQaSetup::CheckoutDetectors()
 {
-  auto CheckDetector = [&] (ca::EDetectorID detID) {
+  auto CheckDetector = [&](ca::EDetectorID detID) {
     if (CbmSetup::Instance()->IsActive(ToCbmModuleId(detID))) {
       fvbUseDet[detID] = true;
     }
@@ -304,6 +304,9 @@ try {
   auto InitHitBranch = [&](const char* brName, ca::EDetectorID detID) {
     if (fvbUseDet[detID]) {
       fvpBrHits[detID] = dynamic_cast<TClonesArray*>(pFairManager->GetObject(brName));
+      if (!fvpBrHits[detID]) {
+        fvbUseDet[detID] = false;  // Disable detectors without hits
+      }
     }
     return static_cast<bool>(fvpBrHits[detID]);
   };