diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c
index 089703b2690e33c6cd2fc881e13ed3562fed6876..73f12a00c585e0d9c900f375ac9d53213846a6de 100644
--- a/res/res_pjsip/pjsip_options.c
+++ b/res/res_pjsip/pjsip_options.c
@@ -107,6 +107,8 @@ static void *contact_status_alloc(const char *name)
 	return status;
 }
 
+AST_MUTEX_DEFINE_STATIC(creation_lock);
+
 /*!
  * \brief Retrieve a ast_sip_contact_status object from sorcery creating
  *        one if not found.
@@ -114,6 +116,7 @@ static void *contact_status_alloc(const char *name)
 struct ast_sip_contact_status *ast_res_pjsip_find_or_create_contact_status(const struct ast_sip_contact *contact)
 {
 	struct ast_sip_contact_status *status;
+	SCOPED_MUTEX(lock, &creation_lock);
 
 	status = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), CONTACT_STATUS,
 		ast_sorcery_object_get_id(contact));
diff --git a/res/res_sorcery_memory.c b/res/res_sorcery_memory.c
index 153235838bb445fb7ac0c32be661bb71298493ef..95cb24835f23777a817c044def3d9edcc5319e50 100644
--- a/res/res_sorcery_memory.c
+++ b/res/res_sorcery_memory.c
@@ -98,7 +98,21 @@ static int sorcery_memory_cmp(void *obj, void *arg, int flags)
 
 static int sorcery_memory_create(const struct ast_sorcery *sorcery, void *data, void *object)
 {
-	ao2_link(data, object);
+	void *existing;
+
+	ao2_lock(data);
+
+	existing = ao2_find(data, ast_sorcery_object_get_id(object), OBJ_KEY | OBJ_NOLOCK);
+	if (existing) {
+		ao2_ref(existing, -1);
+		ao2_unlock(data);
+		return -1;
+	}
+
+	ao2_link_flags(data, object, OBJ_NOLOCK);
+
+	ao2_unlock(data);
+
 	return 0;
 }