diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp
index 390110b0ecd1140fc61dd4cfb990149ae4b5ba26..d2c911a18903e2e7cc6348cfe7435142af33c695 100644
--- a/indra/llprimitive/llgltfmaterial.cpp
+++ b/indra/llprimitive/llgltfmaterial.cpp
@@ -794,6 +794,10 @@ bool LLGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const LLUUID
             mTextureId[i] = new_id;
             res = true;
         }
+        else if (mTextureId[i] == new_id)
+        {
+            res = true;
+        }
     }
 
     if (res)
diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp
index a47b52fddc076934f41180104f2a4557996454bd..1a4729352349f85ae4d4b5387ab41c56de8b6b33 100644
--- a/indra/newview/llfetchedgltfmaterial.cpp
+++ b/indra/newview/llfetchedgltfmaterial.cpp
@@ -183,6 +183,14 @@ bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const
         res = true;
     }
 
+    for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
+    {
+        if (mTextureId[i] == new_id)
+        {
+            res = true;
+        }
+    }
+
     if (res)
     {
         mTrackingIdToLocalTexture[tracking_id] = new_id;
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index 4121df4bac201f641f07465683ccda78c45842b9..5a5fb7474cb32affd24460ca12294dd6a87572a0 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -641,41 +641,49 @@ void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id)
         }
         else if ((*it)->replaceLocalTexture(mTrackingID, old_id, new_id))
         {
-            LLFetchedGLTFMaterial* fetched_mat = dynamic_cast<LLFetchedGLTFMaterial*>((*it).get());
-            if (fetched_mat)
+            it++;
+        }
+        else
+        {
+            // Matching id not found, no longer in use
+            // material would clean itself, remove from the list
+            it = mGLTFMaterialWithLocalTextures.erase(it);
+            end = mGLTFMaterialWithLocalTextures.end();
+        }
+    }
+
+    // Render material consists of base and override materials, make sure replaceLocalTexture
+    // gets called for base and override before applyOverride
+    end = mGLTFMaterialWithLocalTextures.end();
+    for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;)
+    {
+        LLFetchedGLTFMaterial* fetched_mat = dynamic_cast<LLFetchedGLTFMaterial*>((*it).get());
+        if (fetched_mat)
+        {
+            for (LLTextureEntry* entry : fetched_mat->mTextureEntires)
             {
-                for (LLTextureEntry* entry : fetched_mat->mTextureEntires)
+                // Normally a change in applied material id is supposed to
+                // drop overrides thus reset material, but local materials
+                // currently reuse their existing asset id, and purpose is
+                // to preview how material will work in-world, overrides
+                // included, so do an override to render update instead.
+                LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride();
+                if (override_mat)
                 {
-                    // Normally a change in applied material id is supposed to
-                    // drop overrides thus reset material, but local materials
-                    // currently reuse their existing asset id, and purpose is
-                    // to preview how material will work in-world, overrides
-                    // included, so do an override to render update instead.
-                    LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride();
-                    if (override_mat)
+                    // do not create a new material, reuse existing pointer
+                    LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)entry->getGLTFRenderMaterial();
+                    if (render_mat)
                     {
-                        // do not create a new material, reuse existing pointer
-                        LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)entry->getGLTFRenderMaterial();
-                        if (render_mat)
+                        llassert(dynamic_cast<LLFetchedGLTFMaterial*>(entry->getGLTFRenderMaterial()) != nullptr);
                         {
-                            llassert(dynamic_cast<LLFetchedGLTFMaterial*>(entry->getGLTFRenderMaterial()) != nullptr);
-                            {
-                                *render_mat = *fetched_mat;
-                            }
-                            render_mat->applyOverride(*override_mat);
+                            *render_mat = *fetched_mat;
                         }
+                        render_mat->applyOverride(*override_mat);
                     }
                 }
             }
-            ++it;
-        }
-        else
-        {
-            // Matching id not found, no longer in use
-            // material would clean itself, remove from the list
-            it = mGLTFMaterialWithLocalTextures.erase(it);
-            end = mGLTFMaterialWithLocalTextures.end();
         }
+        ++it;
     }
 }
 
diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index 7d1ac3228254812563a1a470324126af4533d910..11a528314e446eaa3f2fb3e79f000c7c5fd1eba4 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -3231,6 +3231,10 @@ bool LLMaterialEditor::setFromSelection()
 
         // Ovverdired might have been updated,
         // refresh state of local textures in overrides
+        // 
+        // Todo: this probably shouldn't be here, but in localbitmap,
+        // subscried to all material overrides if we want copied
+        // objects to get properly updated as well
         LLSelectedTEUpdateOverrides local_tex_func(this);
         selected_objects->applyToNodes(&local_tex_func);
     }