diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 5c648c11e1e7e9ce8d48402478db15562098c1f2..0d53950889dd4c22f015b1148d6f2e46df23b3a3 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -852,6 +852,7 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32
 
 LLSpatialPartition::~LLSpatialPartition()
 {
+    cleanup();
 }
 
 LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 5eda75753e5f3cfb3403fd1f70f0c156af30fa24..87e296012d3249fab20fca7249d274761afb02a6 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -1325,8 +1325,13 @@ LLViewerOctreePartition::LLViewerOctreePartition() :
 	
 LLViewerOctreePartition::~LLViewerOctreePartition()
 {
-	delete mOctree;
-	mOctree = NULL;
+    cleanup();
+}
+
+void LLViewerOctreePartition::cleanup()
+{
+    delete mOctree;
+    mOctree = nullptr;
 }
 
 BOOL LLViewerOctreePartition::isOcclusionEnabled()
@@ -1334,6 +1339,7 @@ BOOL LLViewerOctreePartition::isOcclusionEnabled()
 	return mOcclusionEnabled || LLPipeline::sUseOcclusion > 2;
 }
 
+
 //-----------------------------------------------------------------------------------
 //class LLViewerOctreeCull definitions
 //-----------------------------------------------------------------------------------
diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h
index 11ba7e4f1ec026163fa4d7f2fed6c3ebdddc16a2..e6974b0f84ef715c1fc26b4f819a5ac6c051908b 100644
--- a/indra/newview/llvieweroctree.h
+++ b/indra/newview/llvieweroctree.h
@@ -352,6 +352,10 @@ class LLViewerOctreePartition
 	virtual S32 cull(LLCamera &camera, bool do_occlusion) = 0;
 	BOOL isOcclusionEnabled();
 
+protected:
+    // MUST call from destructor of any derived classes (SL-17276)
+    void cleanup();
+
 public:	
 	U32              mPartitionType;
 	U32              mDrawableType;
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index e10a9f9bcb5b8a20a672c724b3b7fec67fb5e542..db8ad183f0ad1048468f81ba82f1587a59cdd687 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -632,6 +632,13 @@ LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp)
 	new LLVOCacheGroup(mOctree, this);
 }
 
+LLVOCachePartition::~LLVOCachePartition()
+{
+    // SL-17276 make sure to do base class cleanup while this instance
+    // can still be treated as an LLVOCachePartition 
+    cleanup();
+}
+
 bool LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry)
 {
 	llassert(entry->hasVOCacheEntry());
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index c510ff77fcf0b6e73594e0a1aa0eb2ffd5c991a7..55a13d934dd01f4652c6943be6047250bb5f179b 100644
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -189,6 +189,7 @@ class LLVOCachePartition : public LLViewerOctreePartition
 {
 public:
 	LLVOCachePartition(LLViewerRegion* regionp);
+    virtual ~LLVOCachePartition();
 
 	bool addEntry(LLViewerOctreeEntry* entry);
 	void removeEntry(LLViewerOctreeEntry* entry);