diff --git a/Framework/Algorithms/src/AnnularRingAbsorption.cpp b/Framework/Algorithms/src/AnnularRingAbsorption.cpp
index ae6300113a296876ba2f4b0f5094eb3f0c0bed78..8715fb3127e2df0cd07fe7a6d50eb0d01c0f8b6d 100644
--- a/Framework/Algorithms/src/AnnularRingAbsorption.cpp
+++ b/Framework/Algorithms/src/AnnularRingAbsorption.cpp
@@ -178,13 +178,15 @@ AnnularRingAbsorption::createSampleShapeXML(const V3D &upAxis) const {
   const double lowRadiusMtr = (wallMidPtCM - 0.5 * sampleThickCM) / 100.;
   const double uppRadiusMtr = (wallMidPtCM + 0.5 * sampleThickCM) / 100.;
 
-  // Cylinders oriented along Y, with origin at centre of bottom base
+  // Cylinders oriented along Y, with origin at the centre as expected by
+  // the MonteCarloAbsorption algorithm.
+  const V3D bottomCentre{0.0, -sampleHeightCM / 2.0 / 100.0, 0.0}; // in metres.
   const std::string innerCylID = std::string("inner-cyl");
-  const std::string innerCyl = cylinderXML(innerCylID, V3D(), lowRadiusMtr,
-                                           upAxis, sampleHeightCM / 100.0);
+  const std::string innerCyl = cylinderXML(
+      innerCylID, bottomCentre, lowRadiusMtr, upAxis, sampleHeightCM / 100.0);
   const std::string outerCylID = std::string("outer-cyl");
-  const std::string outerCyl = cylinderXML(outerCylID, V3D(), uppRadiusMtr,
-                                           upAxis, sampleHeightCM / 100.0);
+  const std::string outerCyl = cylinderXML(
+      outerCylID, bottomCentre, uppRadiusMtr, upAxis, sampleHeightCM / 100.0);
 
   // Combine shapes
   boost::format algebra("<algebra val=\"(%1% (# %2%))\" />");
diff --git a/Framework/Algorithms/src/SampleCorrections/RectangularBeamProfile.cpp b/Framework/Algorithms/src/SampleCorrections/RectangularBeamProfile.cpp
index b3aa0b2168d826c9b6c507eb66a2176a538befa2..5503e62b37bc6c196efa3b28c478ed43d302d248 100644
--- a/Framework/Algorithms/src/SampleCorrections/RectangularBeamProfile.cpp
+++ b/Framework/Algorithms/src/SampleCorrections/RectangularBeamProfile.cpp
@@ -90,10 +90,10 @@ RectangularBeamProfile::defineActiveRegion(const API::Sample &sample) const {
   const auto &sampleMin(sampleBox.minPoint());
   const auto &sampleMax(sampleBox.maxPoint());
   V3D minPoint, maxPoint;
-  minPoint[m_horIdx] = m_min[m_horIdx];
-  maxPoint[m_horIdx] = m_min[m_horIdx] + m_width;
-  minPoint[m_upIdx] = m_min[m_upIdx];
-  maxPoint[m_upIdx] = m_min[m_upIdx] + m_height;
+  minPoint[m_horIdx] = std::max(sampleMin[m_horIdx], m_min[m_horIdx]);
+  maxPoint[m_horIdx] = std::min(sampleMax[m_horIdx], m_min[m_horIdx] + m_width);
+  minPoint[m_upIdx] = std::max(sampleMin[m_upIdx], m_min[m_upIdx]);
+  maxPoint[m_upIdx] = std::min(sampleMax[m_upIdx], m_min[m_upIdx] + m_height);
   minPoint[m_beamIdx] = sampleMin[m_beamIdx];
   maxPoint[m_beamIdx] = sampleMax[m_beamIdx];
 
diff --git a/Framework/Algorithms/test/AnnularRingAbsorptionTest.h b/Framework/Algorithms/test/AnnularRingAbsorptionTest.h
index c3131a7605dfc62b27e0a04b6682aa016d4bf9a6..368464508ac3f10825c77ffae089bb965b12668d 100644
--- a/Framework/Algorithms/test/AnnularRingAbsorptionTest.h
+++ b/Framework/Algorithms/test/AnnularRingAbsorptionTest.h
@@ -43,11 +43,11 @@ public:
     MatrixWorkspace_sptr outWS = alg->getProperty("OutputWorkspace");
     TS_ASSERT(outWS);
 
-    const double delta(1e-08);
+    const double delta(1e-04);
     const size_t middle_index = 4;
-    TS_ASSERT_DELTA(0.96859812, outWS->readY(0).front(), delta);
-    TS_ASSERT_DELTA(0.79254304, outWS->readY(0)[middle_index], delta);
-    TS_ASSERT_DELTA(0.67064972, outWS->readY(0).back(), delta);
+    TS_ASSERT_DELTA(0.9694, outWS->readY(0).front(), delta);
+    TS_ASSERT_DELTA(0.8035, outWS->readY(0)[middle_index], delta);
+    TS_ASSERT_DELTA(0.6530, outWS->readY(0).back(), delta);
   }
 
   //-------------------- Failure cases --------------------------------
diff --git a/Framework/Algorithms/test/RectangularBeamProfileTest.h b/Framework/Algorithms/test/RectangularBeamProfileTest.h
index 973a622ca00d9708c449a1db986fc6b036147363..32b043458930dc56387350a7714a069d0ab64981 100644
--- a/Framework/Algorithms/test/RectangularBeamProfileTest.h
+++ b/Framework/Algorithms/test/RectangularBeamProfileTest.h
@@ -82,7 +82,22 @@ public:
     TS_ASSERT_EQUALS(V3D(1.0, 0, 0), ray.unitDir);
   }
 
-  void test_DefineActiveRegion() {
+  void test_DefineActiveRegion_beam_larger_than_sample() {
+    using Mantid::API::Sample;
+    using Mantid::Kernel::V3D;
+    const double width(3.3), height(6.9);
+    const V3D center;
+    RectangularBeamProfile profile(createTestFrame(), center, width, height);
+    Sample testSample;
+    testSample.setShape(*ComponentCreationHelper::createSphere(0.5));
+
+    auto region = profile.defineActiveRegion(testSample);
+    TS_ASSERT(region.isNonNull());
+    TS_ASSERT_EQUALS(V3D(-0.5, -0.5, -0.5), region.minPoint());
+    TS_ASSERT_EQUALS(V3D(0.5, 0.5, 0.5), region.maxPoint());
+  }
+
+  void test_DefineActiveRegion_beam_smaller_than_sample() {
     using Mantid::API::Sample;
     using Mantid::Kernel::V3D;
     const double width(0.1), height(0.2);
diff --git a/docs/source/release/v3.10.0/framework.rst b/docs/source/release/v3.10.0/framework.rst
index 4e1e6414839faf35a665112ef331b2acfbe1efd3..34bbaee7f5eacd18aecd299769bdcb6ff5864361 100644
--- a/docs/source/release/v3.10.0/framework.rst
+++ b/docs/source/release/v3.10.0/framework.rst
@@ -82,6 +82,7 @@ Bugs
 
 - We have fixed a bug where Mantid could crash when deleting a large number of workspaces.
 - Fixed a bug in :ref:`ConvertToMD <algm-ConvertToMD>` causing it to fail with the error "Run::storeEnergyBinBoundaries - Inconsistent start & end values" if monitors were all NaN, Inf, or zero.
+- Fixed a bug in illuminated volume calculation which could make :ref:`MonteCarloAbsorption` fail.
 
 CurveFitting
 ------------