diff --git a/Tr/TrackTools/src/TrackInterpolator.cpp b/Tr/TrackTools/src/TrackInterpolator.cpp
index 4a494370a1d6c6eec86c5e4aa49068fb957d7cd4..1fdfbaa24fe880a5e5e26615a2377debdfabee8d 100644
--- a/Tr/TrackTools/src/TrackInterpolator.cpp
+++ b/Tr/TrackTools/src/TrackInterpolator.cpp
@@ -168,30 +168,59 @@ StatusCode TrackInterpolator::Interpolator( const TFitResult& fitResult, const T
     }
   }
 
-  // Get the filtered states
-  State stateDown, stateUp;
-
-  // TrackMasterFit
-  stateDown = filteredStateForward( *prevnode );
-  stateUp   = filteredStateBackward( *nextnode );
-
-  // extrapolate the upstream and downstream states
-  auto sc = m_extrapolator->propagate( stateDown, z, geometry );
+  // downstream propagation
+  const auto  Down_refvector_at_origin = ( *prevnode ).refVector();
+  auto        Down_refvector_at_target = Down_refvector_at_origin;
+  TrackMatrix F_Down;
+  auto        sc = m_extrapolator->propagate( Down_refvector_at_target, z, geometry, &F_Down );
   if ( sc.isFailure() ) {
-    if ( msgLevel( MSG::DEBUG ) )
-      debug() << "Error propagating downstream state to z = " << z << std::endl << "state = " << stateDown << endmsg;
+    if ( msgLevel( MSG::DEBUG ) ) {
+      debug() << "Error propagating downstream state to z = " << z << " tracktype = " << track.type() << std::endl
+              << "state = " << state( *prevnode ) << endmsg;
+    }
     ++m_propagate_downstream_failure;
     return sc;
   }
+  auto stateDown = filteredStateForward( *prevnode );
+  // propagate the filtered state using the reference
+  stateDown.stateVector() = Down_refvector_at_target.parameters() +
+                            F_Down * ( stateDown.stateVector() - Down_refvector_at_origin.parameters() );
+  stateDown.covariance() = ROOT::Math::Similarity( F_Down, stateDown.covariance() );
+  stateDown.setZ( z );
+
+  if ( msgLevel( MSG::DEBUG ) ) {
+    debug() << "propagating downstream state:" << std::endl
+            << state( *prevnode ) << std::endl
+            << "to new state at z = " << z << ":" << std::endl
+            << stateDown << endmsg;
+  }
 
-  sc = m_extrapolator->propagate( stateUp, z, geometry );
+  // upstream propagation
+  const auto  Up_refvector_at_origin = ( *nextnode ).refVector();
+  auto        Up_refvector_at_target = Up_refvector_at_origin;
+  TrackMatrix F_Up;
+  sc = m_extrapolator->propagate( Up_refvector_at_target, z, geometry, &F_Up );
   if ( sc.isFailure() ) {
-    if ( msgLevel( MSG::DEBUG ) )
+    if ( msgLevel( MSG::DEBUG ) ) {
       debug() << "Error propagating upstream state to z = " << z << " tracktype = " << track.type() << std::endl
-              << "state = " << stateUp << endmsg;
+              << "state = " << state( *nextnode ) << endmsg;
+    }
     ++m_propagate_upstream_failure;
     return sc;
   }
+  auto stateUp = filteredStateBackward( *nextnode );
+  // propagate the filtered state using the reference
+  stateUp.stateVector() =
+      Up_refvector_at_target.parameters() + F_Up * ( stateUp.stateVector() - Up_refvector_at_origin.parameters() );
+  stateUp.covariance() = ROOT::Math::Similarity( F_Up, stateUp.covariance() );
+  stateUp.setZ( z );
+
+  if ( msgLevel( MSG::DEBUG ) ) {
+    debug() << "propagating upstream state:" << std::endl
+            << state( *nextnode ) << std::endl
+            << "to new state at z = " << z << ":" << std::endl
+            << stateUp << endmsg;
+  }
 
   // Get the predicted downstream state and invert the covariance matrix
   const TrackVector& stateDownX    = stateDown.stateVector();