diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index d5d289738372a49025370af172f59498cc260e23..b27fbbff88667418e8a6baa3e6425d5807fbbee0 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1786,6 +1786,12 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
 	//llinfos << "LLInventoryModel::addItem()" << llendl;
 	if(item)
 	{
+		// This condition means that we tried to add a link without the baseobj being in memory.
+		// The item will show up as a broken link.
+		if (item->getIsBrokenLink())
+		{
+			llwarns << "Add link item without baseobj present ( itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) " << llendl;
+		}
 		mItemMap[item->getUUID()] = item;
 		//mInventory[item->getUUID()] = item;
 	}
@@ -2122,16 +2128,28 @@ bool LLInventoryModel::loadSkeleton(
 			cat_map_t::iterator unparented = mCategoryMap.end();
 			for(int i = 0; i < count; ++i)
 			{
-				cat_map_t::iterator cit = mCategoryMap.find(items[i]->getParentUUID());
+				LLViewerInventoryItem *item = items[i].get();
+				cat_map_t::iterator cit = mCategoryMap.find(item->getParentUUID());
 				
 				if(cit != unparented)
 				{
 					LLViewerInventoryCategory* cat = cit->second;
 					if(cat->getVersion() != NO_VERSION)
 					{
-						addItem(items[i]);
+						if (item->getIsBrokenLink())
+						{
+							llinfos << "Attempted to cached link item without baseobj present ( itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) " << llendl;
+							child_counts[cat->getUUID()].mValue = -1; // Invalidate this category's cache.
+							continue;
+						}
+						addItem(item);
 						cached_item_count += 1;
-						++child_counts[cat->getUUID()];
+
+						// If this category had any broken links, keep it invalidated.
+						if (child_counts[cat->getUUID()].mValue != -1)
+						{
+							++child_counts[cat->getUUID()];
+						}
 					}
 				}
 			}
@@ -2161,12 +2179,16 @@ bool LLInventoryModel::loadSkeleton(
 				the_count = child_counts.find(cat->getUUID());
 				if(the_count != no_child_counts)
 				{
-					cat->setDescendentCount((*the_count).second.mValue);
-				}
-				else
-				{
-					cat->setDescendentCount(0);
+					S32 num_descendents = (*the_count).second.mValue;
+
+					// -1 means that one of the children was a broken link, so we can't consider this folder successfully cached.
+					if (num_descendents != -1) 
+					{
+						cat->setDescendentCount(num_descendents);
+						continue;
+					}
 				}
+				cat->setDescendentCount(0);
 			}
 		}
 
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 78e8f084c70d420b33464d5380ca824ec01c9671..9a090be76aa85bd001f8b5a7a7caddd25d71edbc 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -1185,6 +1185,17 @@ U32 LLViewerInventoryItem::getCRC32() const
 	return LLInventoryItem::getCRC32();	
 }
 
+// This returns true if the item that this item points to 
+// doesn't exist in memory (i.e. LLInventoryModel).  The baseitem
+// might still be in the database but just not loaded yet.
+bool LLViewerInventoryItem::getIsBrokenLink() const
+{
+	// If the item's type resolves to be a link, that means either:
+	// A. It wasn't able to perform indirection, i.e. the baseobj doesn't exist in memory.
+	// B. It's pointing to another link, which is illegal.
+	return LLAssetType::lookupIsLinkType(getType());
+}
+
 const LLViewerInventoryItem *LLViewerInventoryItem::getLinkedItem() const
 {
 	if (mType == LLAssetType::AT_LINK)
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 10309d023be2abad9c314e4f1d5f57434376dac8..8920fb053bcb9c3701445b431d74e94a33348f7d 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -141,6 +141,7 @@ class LLViewerInventoryItem : public LLInventoryItem, public boost::signals2::tr
 	};
 	LLTransactionID getTransactionID() const { return mTransactionID; }
 	
+	bool getIsBrokenLink() const; // true if the baseitem this points to doesn't exist in memory.
 	const LLViewerInventoryItem *getLinkedItem() const;
 	const LLViewerInventoryCategory *getLinkedCategory() const;