diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index e78ea88b94ff65f14d0a654d6e109fad15ca5621..a93b0c1357924d434693a5225433305196336ca3 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -2190,8 +2190,6 @@ void LLInitialWearablesFetch::processContents()
 	else
 	{
 		processWearablesMessage();
-		// Create links for attachments that may have arrived before the COF existed.
-		LLAppearanceManager::instance().linkRegisteredAttachments();
 	}
 	delete this;
 }
@@ -2200,7 +2198,8 @@ class LLFetchAndLinkObserver: public LLInventoryFetchObserver
 {
 public:
 	LLFetchAndLinkObserver(LLInventoryFetchObserver::item_ref_t& ids):
-		m_ids(ids)
+		m_ids(ids),
+		LLInventoryFetchObserver(true)
 	{
 		llwarns << "LLFetchAndLinkObserver" << llendl;
 	}
@@ -2220,13 +2219,12 @@ class LLFetchAndLinkObserver: public LLInventoryFetchObserver
 			LLViewerInventoryItem *item = gInventory.getItem(*it);
 			if (!item)
 			{
-				llwarns << "LLFetchAndLinkObserver fetch failed!" << llendl;
+				llwarns << "fetch failed!" << llendl;
 				continue;
 			}
 			link_inventory_item(gAgent.getID(), item->getLinkedUUID(), LLAppearanceManager::instance().getCOF(), item->getName(),
 								LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
 		}
-
 	}
 private:
 	LLInventoryFetchObserver::item_ref_t m_ids;
@@ -2261,6 +2259,28 @@ void LLInitialWearablesFetch::processWearablesMessage()
 			}
 		}
 
+		// Add all current attachments to the requested items as well.
+		LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
+		if( avatar )
+		{
+			for (LLVOAvatar::attachment_map_t::const_iterator iter = avatar->mAttachmentPoints.begin(); 
+				 iter != avatar->mAttachmentPoints.end(); ++iter)
+			{
+				LLViewerJointAttachment* attachment = iter->second;
+				if (!attachment) continue;
+				for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+					 attachment_iter != attachment->mAttachedObjects.end();
+					 ++attachment_iter)
+				{
+					LLViewerObject* attached_object = (*attachment_iter);
+					if (!attached_object) continue;
+					const LLUUID& item_id = attached_object->getItemID();
+					if (item_id.isNull()) continue;
+					ids.push_back(item_id);
+				}
+			}
+		}
+
 		// Need to fetch the inventory items for ids, then create links to them after they arrive.
 		LLFetchAndLinkObserver *fetcher = new LLFetchAndLinkObserver(ids);
 		fetcher->fetchItems(ids);
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 60c6061e966a7860f43c85b35962fcae353a1927..bec70ce827ef0af25e65c78064397c5b172adc21 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -990,6 +990,10 @@ void LLAppearanceManager::registerAttachment(const LLUUID& item_id)
 			   gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
 			   gInventory.notifyObservers();
 		   }
+		   else
+		   {
+			   llwarns << "missing item, can't link" << llendl;
+		   }
 	   }
 	   else
 	   {
diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
index e904fb6c9210faafa299eb39b5d8e502c52b3f15..06f4b36df3021643a311cb1de71053ae7fc977b8 100644
--- a/indra/newview/llinventoryobserver.cpp
+++ b/indra/newview/llinventoryobserver.cpp
@@ -112,11 +112,20 @@ void LLInventoryFetchObserver::changed(U32 mask)
 			LLViewerInventoryItem* item = gInventory.getItem(*it);
 			if(!item)
 			{
-				// BUG: This can cause done() to get called prematurely below.
-				// This happens with the LLGestureInventoryFetchObserver that
-				// loads gestures at startup. JC
-				//it = mIncomplete.erase(it);
-				++it;
+				if (mRetryIfMissing)
+				{
+					// BAP changed to skip these items, so we should keep retrying until they arrive.
+					// Did not make this the default behavior because of uncertainty about impact -
+					// could cause some observers that currently complete to wait forever.
+					++it;
+				}
+				else
+				{
+					// BUG: This can cause done() to get called prematurely below.
+					// This happens with the LLGestureInventoryFetchObserver that
+					// loads gestures at startup. JC
+					it = mIncomplete.erase(it);
+				}
 				continue;
 			}
 			if(item->isComplete())
diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h
index 384e6292e8a6aad73f8e0c74d0faac1d9dc2fdc1..3a083e913b9ecd0c14767450e53ebd31f708a5d1 100644
--- a/indra/newview/llinventoryobserver.h
+++ b/indra/newview/llinventoryobserver.h
@@ -106,7 +106,7 @@ class LLInventoryCompletionObserver : public LLInventoryObserver
 class LLInventoryFetchObserver : public LLInventoryObserver
 {
 public:
-	LLInventoryFetchObserver() {}
+	LLInventoryFetchObserver(bool retry_if_missing = false): mRetryIfMissing(retry_if_missing) {}
 	virtual void changed(U32 mask);
 
 	typedef std::vector<LLUUID> item_ref_t;
@@ -116,6 +116,7 @@ class LLInventoryFetchObserver : public LLInventoryObserver
 	virtual void done() = 0;
 
 protected:
+	bool mRetryIfMissing;
 	item_ref_t mComplete;
 	item_ref_t mIncomplete;
 };