diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 244491bc356048d742b28c5e9b8acb67d7ef75d1..c691527c3fedb3a68009260845d9ea94a4f83ff5 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -4232,6 +4232,37 @@ bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id)
     return false;
 }
 
+bool LLMeshRepository::hasSkinInfo(const LLUUID& mesh_id)
+{
+    if (mesh_id.isNull())
+    {
+        return false;
+    }
+
+    if (mThread->hasSkinInfoInHeader(mesh_id))
+    {
+        return true;
+    }
+
+    const LLMeshSkinInfo* skininfo = getSkinInfo(mesh_id);
+    if (skininfo)
+    {
+        return true;
+    }
+
+    return false;
+}
+
+bool LLMeshRepository::hasHeader(const LLUUID& mesh_id)
+{
+    if (mesh_id.isNull())
+    {
+        return false;
+    }
+
+    return mThread->hasHeader(mesh_id);
+}
+
 bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id)
 {
     LLMutexLock lock(mHeaderMutex);
@@ -4248,6 +4279,29 @@ bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id)
     return false;
 }
 
+bool LLMeshRepoThread::hasSkinInfoInHeader(const LLUUID& mesh_id)
+{
+    LLMutexLock lock(mHeaderMutex);
+    mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
+    if (iter != mMeshHeader.end() && iter->second.first > 0)
+    {
+        LLMeshHeader& mesh = iter->second.second;
+        if (mesh.mSkinOffset >= 0
+            && mesh.mSkinSize > 0)
+        {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+bool LLMeshRepoThread::hasHeader(const LLUUID& mesh_id)
+{
+    LLMutexLock lock(mHeaderMutex);
+    mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
+    return iter != mMeshHeader.end();
+}
 
 void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures,
 								   bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position,
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 26b0d5c8e29f46c315eebec042dd3fabc5212596..184148d6185fb9a5fd25d555a6516ccea2ce311a 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -432,6 +432,8 @@ class LLMeshRepoThread final : public LLThread
 	EMeshProcessingResult decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
 	EMeshProcessingResult physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
 	bool hasPhysicsShapeInHeader(const LLUUID& mesh_id);
+    bool hasSkinInfoInHeader(const LLUUID& mesh_id);
+    bool hasHeader(const LLUUID& mesh_id);
 
 	bool loadInfoFromFilesystem(const LLUUID& mesh_id, MeshHeaderInfo& info, boost::function<bool(const LLUUID&, U8*, S32)> fn);
 
@@ -685,6 +687,8 @@ class LLMeshRepository
 	LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id);
 	void fetchPhysicsShape(const LLUUID& mesh_id);
 	bool hasPhysicsShape(const LLUUID& mesh_id);
+    bool hasSkinInfo(const LLUUID& mesh_id);
+    bool hasHeader(const LLUUID& mesh_id);
 	
 	void buildHull(const LLVolumeParams& params, S32 detail);
 	void buildPhysicsMesh(LLModel::Decomposition& decomp);
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index a9144eed50e03c196732d4fdf5eaf5eee4760108..01f97f5faa87bd8da78b05f5e6bfc665f8afa607 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -236,7 +236,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
     mColorChanged = FALSE;
 	mSpotLightPriority = 0.f;
 
-	mSkinInfoFailed = false;
+    mSkinInfoUnavaliable = false;
 	mSkinInfo = NULL;
 
 	mMediaImplList.resize(getNumTEs());
@@ -1106,7 +1106,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
 				if (mSkinInfo && mSkinInfo->mMeshID != volume_params.getSculptID())
 				{
 					mSkinInfo = NULL;
-					mSkinInfoFailed = false;
+					mSkinInfoUnavaliable = false;
 				}
 
 				if (!getVolume()->isMeshAssetLoaded())
@@ -1119,13 +1119,32 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
 					}
 				}
 				
-				if (!mSkinInfo && !mSkinInfoFailed)
+				if (!mSkinInfo && !mSkinInfoUnavaliable)
 				{
+#if 1 // ALCHEMY
 					const LLMeshSkinInfo* skin_info = gMeshRepo.getSkinInfo(volume_params.getSculptID(), this);
 					if (skin_info)
 					{
 						notifySkinInfoLoaded(skin_info);
 					}
+#else
+                    LLUUID mesh_id = volume_params.getSculptID();
+                    if (gMeshRepo.hasHeader(mesh_id) && !gMeshRepo.hasSkinInfo(mesh_id))
+                    {
+                        // If header is present but has no data about skin,
+                        // no point fetching
+                        mSkinInfoUnavaliable = true;
+                    }
+
+                    if (!mSkinInfoUnavaliable)
+                    {
+                        const LLMeshSkinInfo* skin_info = gMeshRepo.getSkinInfo(mesh_id, this);
+                        if (skin_info)
+                        {
+                            notifySkinInfoLoaded(skin_info);
+                        }
+                    }
+#endif
 				}
 			}
 			else // otherwise is sculptie
@@ -1160,7 +1179,7 @@ void LLVOVolume::updateSculptTexture()
 			mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 		}
 
-		mSkinInfoFailed = false;
+        mSkinInfoUnavaliable = false;
 		mSkinInfo = NULL;
 	}
 	else
@@ -1201,6 +1220,18 @@ void LLVOVolume::notifyMeshLoaded()
 	mSculptChanged = TRUE;
 	gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY);
 
+#if 0 // ALCHEMY
+    if (!mSkinInfo && !mSkinInfoUnavaliable)
+    {
+        // Header was loaded, update skin info state from header
+        LLUUID mesh_id = getVolume()->getParams().getSculptID();
+        if (!gMeshRepo.hasSkinInfo(mesh_id))
+        {
+            mSkinInfoUnavaliable = true;
+        }
+    }
+#endif
+
     LLVOAvatar *av = getAvatar();
     if (av && !isAnimatedObject())
     {
@@ -1218,7 +1249,7 @@ void LLVOVolume::notifyMeshLoaded()
 
 void LLVOVolume::notifySkinInfoLoaded(const LLMeshSkinInfo* skin)
 {
-	mSkinInfoFailed = false;
+    mSkinInfoUnavaliable = false;
 	mSkinInfo = skin;
 
 	notifyMeshLoaded();
@@ -1226,7 +1257,7 @@ void LLVOVolume::notifySkinInfoLoaded(const LLMeshSkinInfo* skin)
 
 void LLVOVolume::notifySkinInfoUnavailable()
 {
-	mSkinInfoFailed = true;
+	mSkinInfoUnavaliable = true;
 	mSkinInfo = nullptr;
 }
 
@@ -5572,11 +5603,21 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
             gGLTFMaterialList.applyQueuedOverrides(vobj);
 
             bool is_mesh = vobj->isMesh();
-			if (is_mesh &&
-				((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))
-			{
-				continue;
-			}
+            if (is_mesh)
+            {
+                if ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded())
+                    || !gMeshRepo.meshRezEnabled())
+                {
+                    // Waiting for asset to fetch
+                    continue;
+                }
+
+                if (!vobj->getSkinInfo() && !vobj->isSkinInfoUnavaliable())
+                {
+                     // Waiting for skin info to fetch
+                     continue;
+                }
+            }
 
 			LLVolume* volume = vobj->getVolume();
 			if (volume)
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 32da6583ce2732111dbdc686fbda855102fc6a15..2337c6abc0f6798e132a577abfaead7a69d97d3b 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -334,6 +334,7 @@ class LLVOVolume final : public LLViewerObject
 	BOOL setIsFlexible(BOOL is_flexible);
 
     const LLMeshSkinInfo* getSkinInfo() const;
+    const bool isSkinInfoUnavaliable() const { return mSkinInfoUnavaliable; }
 
     //convenience accessor for mesh ID (which is stored in sculpt id for legacy reasons)
     const LLUUID& getMeshID() const { return getVolume()->getParams().getSculptID(); }
@@ -484,7 +485,7 @@ class LLVOVolume final : public LLViewerObject
 
 	LLPointer<LLRiggedVolume> mRiggedVolume;
 
-	bool mSkinInfoFailed;
+	bool mSkinInfoUnavaliable;
 	LLConstPointer<LLMeshSkinInfo> mSkinInfo;
 	// statics
 public: