diff --git a/Core/Particle/Particle.cpp b/Core/Particle/Particle.cpp
index ddd0191e308ec0677527ef4138f8072e74a3ced0..7ad9883a7cdc1cc84f7b9175323651f63f7e0d8d 100644
--- a/Core/Particle/Particle.cpp
+++ b/Core/Particle/Particle.cpp
@@ -69,6 +69,8 @@ SlicedParticle Particle::createSlicedParticle(ZLimits limits) const
         P_rotation.reset(mP_rotation->clone());
     std::unique_ptr<IFormFactor> P_temp_ff(
                 mP_form_factor->createSlicedFormFactor(limits, *P_rotation, m_position));
+    if (!P_temp_ff)
+        return {};
     std::unique_ptr<FormFactorDecoratorMaterial> P_ff(new FormFactorDecoratorMaterial(*P_temp_ff));
     double volume = P_temp_ff->volume();
     Material transformed_material(
diff --git a/Core/Particle/ParticleCoreShell.cpp b/Core/Particle/ParticleCoreShell.cpp
index 01c24ce0e78fff3765862035378d75bf9255af07..e5efd5fd197435badbfb7233cb5bc87ca0ae31e4 100644
--- a/Core/Particle/ParticleCoreShell.cpp
+++ b/Core/Particle/ParticleCoreShell.cpp
@@ -53,8 +53,6 @@ SlicedParticle ParticleCoreShell::createSlicedParticle(ZLimits limits) const
     P_core->rotate(*P_rotation);
     P_core->translate(m_position);
     auto sliced_core = P_core->createSlicedParticle(limits);
-    if (!sliced_core.mP_slicedff || sliced_core.m_regions.size()!=1)
-        return {};
 
     // shell
     std::unique_ptr<Particle> P_shell(mp_shell->clone());
@@ -64,6 +62,14 @@ SlicedParticle ParticleCoreShell::createSlicedParticle(ZLimits limits) const
     if (!sliced_shell.mP_slicedff)
         return {};
 
+    SlicedParticle result;
+    // if core out of limits, return sliced shell
+    if (!sliced_core.mP_slicedff) {
+        result.mP_slicedff.reset(sliced_shell.mP_slicedff.release());
+        result.m_regions.push_back(sliced_shell.m_regions.back());
+        return result;
+    }
+
     // set core ambient material
     if (sliced_shell.m_regions.size()!=1)
         return {};
@@ -71,7 +77,6 @@ SlicedParticle ParticleCoreShell::createSlicedParticle(ZLimits limits) const
     sliced_core.mP_slicedff->setAmbientMaterial(shell_material);
 
     // construct sliced particle
-    SlicedParticle result;
     sliced_shell.m_regions.back().m_volume -= sliced_core.m_regions.back().m_volume;
     result.mP_slicedff.reset(new FormFactorCoreShell(sliced_core.mP_slicedff.release(),
                                                      sliced_shell.mP_slicedff.release()));
diff --git a/Core/Scattering/IFormFactor.cpp b/Core/Scattering/IFormFactor.cpp
index 5d8723f467dcb85a9511a87618c3bdd36b4b5467..e904de763ed58bf491f8fb1e491f04d7f94eb70a 100644
--- a/Core/Scattering/IFormFactor.cpp
+++ b/Core/Scattering/IFormFactor.cpp
@@ -25,6 +25,8 @@
 namespace {
 bool ShapeIsContainedInLimits(const IFormFactor& formfactor, ZLimits limits,
                               const IRotation& rot, kvector_t translation);
+bool ShapeOutsideLimits(const IFormFactor& formfactor, ZLimits limits,
+                        const IRotation& rot, kvector_t translation);
 }
 
 IFormFactor::~IFormFactor() {}
@@ -34,6 +36,8 @@ IFormFactor* IFormFactor::createSlicedFormFactor(ZLimits limits, const IRotation
 {
     if (ShapeIsContainedInLimits(*this, limits, rot, translation))
         return CreateTransformedFormFactor(*this, rot, translation);
+    if (ShapeOutsideLimits(*this, limits, rot, translation))
+        return nullptr;
     if (canSliceAnalytically(rot))
         return sliceFormFactor(limits, rot, translation);
     throw std::runtime_error(getName() + "::createSlicedFormFactor error: not supported for "
@@ -96,4 +100,17 @@ bool ShapeIsContainedInLimits(const IFormFactor& formfactor, ZLimits limits,
         return false;
     return true;
 }
+bool ShapeOutsideLimits(const IFormFactor& formfactor, ZLimits limits,
+                        const IRotation& rot, kvector_t translation)
+{
+    double zbottom = formfactor.bottomZ(rot) + translation.z();
+    double ztop = formfactor.topZ(rot) + translation.z();
+    OneSidedLimit lower_limit = limits.lowerLimit();
+    OneSidedLimit upper_limit = limits.upperLimit();
+    if (!upper_limit.m_limitless && zbottom >= upper_limit.m_value)
+        return true;
+    if (!lower_limit.m_limitless && ztop <= lower_limit.m_value)
+        return true;
+    return false;
+}
 }