diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c
index 8dec9570d71ecd2ef91c916d59a10994fffd0c94..beb35346a84bcdbddb132245c067525a977054ef 100644
--- a/coreapi/linphonecore.c
+++ b/coreapi/linphonecore.c
@@ -2555,6 +2555,8 @@ static void linphone_core_free_payload_types(LinphoneCore *lc) {
 }
 
 void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message) {
+	ms_message("Switching LinphoneCore [%p] from state %s to %s", lc, linphone_global_state_to_string(lc->state),
+	           linphone_global_state_to_string(gstate));
 	lc->state = gstate;
 	linphone_core_notify_global_state_changed(lc, gstate, message);
 }
diff --git a/coreapi/tester_utils.h b/coreapi/tester_utils.h
index 8a127130bf9694d59e11fe488668869b593d2fba..619c329b0ab6c91ba59a2853fefe02752c5d4e4d 100644
--- a/coreapi/tester_utils.h
+++ b/coreapi/tester_utils.h
@@ -393,6 +393,8 @@ LINPHONE_PUBLIC void linphone_config_simulate_read_failure(bool_t value);
 
 LINPHONE_PUBLIC void linphone_payload_type_set_priority_bonus(LinphonePayloadType *pt, bool_t value);
 
+LINPHONE_PUBLIC bool_t linphone_account_lime_enabled(LinphoneAccount *account);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/account/account.cpp b/src/account/account.cpp
index db2d6f1af3b0742ff40acc962039994b529c0b8a..25067a116ae10d9b0c298a57e4dd5951a3429711 100644
--- a/src/account/account.cpp
+++ b/src/account/account.cpp
@@ -256,6 +256,18 @@ void Account::setSendPublish(bool sendPublish) {
 
 void Account::setNeedToRegister(bool needToRegister) {
 	mNeedToRegister = needToRegister;
+	if (mNeedToRegister) {
+		try {
+			auto engine = getCore()->getEncryptionEngine();
+			if (engine && mParams) {
+				if (!mParams->getLimeServerUrl().empty() || !getCore()->getX3dhServerUrl().empty()) {
+					mLimeUserAccountStatus = LimeUserAccountStatus::LimeUserAccountNeedCreation;
+				}
+			}
+		} catch (const bad_weak_ptr &) {
+			// Core pointer is null
+		}
+	}
 }
 
 void Account::setDeletionDate(time_t deletionDate) {
@@ -417,6 +429,10 @@ void Account::setDependency(std::shared_ptr<Account> dependency) {
 	}
 }
 
+void Account::setLimeUserAccountStatus(LimeUserAccountStatus status) {
+	mLimeUserAccountStatus = status;
+}
+
 // -----------------------------------------------------------------------------
 
 int Account::getAuthFailure() const {
@@ -493,6 +509,10 @@ std::shared_ptr<Account> Account::getDependency() {
 	return mDependency;
 }
 
+LimeUserAccountStatus Account::getLimeUserAccountStatus() const {
+	return mLimeUserAccountStatus;
+}
+
 // -----------------------------------------------------------------------------
 
 std::shared_ptr<Address> Account::guessContactForRegister() {
@@ -951,10 +971,30 @@ int Account::done() {
 			}
 		}
 		mNeedToRegister = true;
+		try {
+			auto engine = getCore()->getEncryptionEngine();
+			if (engine && mParams) {
+				if (!mParams->getLimeServerUrl().empty() || !getCore()->getX3dhServerUrl().empty()) {
+					mLimeUserAccountStatus = LimeUserAccountStatus::LimeUserAccountNeedCreation;
+				}
+			}
+		} catch (const bad_weak_ptr &) {
+			// Core pointer is null
+		}
 	}
 
 	if (mRegisterChanged) {
 		mNeedToRegister = true;
+		try {
+			auto engine = getCore()->getEncryptionEngine();
+			if (engine && mParams) {
+				if (!mParams->getLimeServerUrl().empty() || !getCore()->getX3dhServerUrl().empty()) {
+					mLimeUserAccountStatus = LimeUserAccountStatus::LimeUserAccountNeedCreation;
+				}
+			}
+		} catch (const bad_weak_ptr &) {
+			// Core pointer is null
+		}
 		mRegisterChanged = false;
 	}
 
@@ -989,18 +1029,39 @@ LinphoneCore *Account::getCCore() const {
 }
 
 void Account::update() {
-	if (mNeedToRegister) {
-		if (canRegister()) {
-			registerAccount();
-			mNeedToRegister = false;
+	auto engine = getCore()->getEncryptionEngine();
+	if (engine && (!mParams->getLimeServerUrl().empty() || !getCore()->getX3dhServerUrl().empty()) &&
+	    mLimeUserAccountStatus == LimeUserAccountStatus::LimeUserAccountNeedCreation) {
+		shared_ptr<Address> addr = mContactAddress;
+		if (!addr) {
+			shared_ptr<Address> sip = getAccountParams()->getIdentityAddress();
+			if (sip) {
+				auto gr = getCCore()->sal->getUuid();
+				if (gr.empty()) return;
+				addr = sip->clone()->toSharedPtr();
+				addr->setUriParam("gr", "urn:uuid:" + gr);
+			}
 		}
-	}
-	if (mSendPublish && (mState == LinphoneRegistrationOk || mState == LinphoneRegistrationCleared)) {
-		if (mPresenceModel == nullptr) {
-			setPresenceModel(getCCore()->presence_model);
+		auto account = this->getSharedFromThis();
+		if (addr) engine->createLimeUser(account, addr->asStringUriOnly());
+	} else if (!engine || (engine && (mLimeUserAccountStatus == LimeUserAccountStatus::LimeUserAccountCreated ||
+	                                  mLimeUserAccountStatus == LimeUserAccountStatus::LimeUserAccountCreationSkiped ||
+	                                  mLimeUserAccountStatus == LimeUserAccountStatus::LimeUserAccountNone))) {
+		/* Either lime isn't enabled
+		 * Or lime is enabled, and the Lime User Creation succeed or failed (so skip it and register) */
+		if (mNeedToRegister) {
+			if (canRegister()) {
+				registerAccount();
+				mNeedToRegister = false;
+			}
+		}
+		if (mSendPublish && (mState == LinphoneRegistrationOk || mState == LinphoneRegistrationCleared)) {
+			if (mPresenceModel == nullptr) {
+				setPresenceModel(getCCore()->presence_model);
+			}
+			sendPublish();
+			mSendPublish = false;
 		}
-		sendPublish();
-		mSendPublish = false;
 	}
 }
 
@@ -1361,7 +1422,8 @@ void Account::onLimeServerUrlChanged(const std::string &limeServerUrl) {
 	// If the lime server URL has changed, then propagate the change to the encryption engine
 	auto encryptionEngine = getCore()->getEncryptionEngine();
 	if (encryptionEngine && (encryptionEngine->getEngineType() == EncryptionEngine::EngineType::LimeX3dh)) {
-		encryptionEngine->onServerUrlChanged(getSharedFromThis(), limeServerUrl);
+		auto account = this->getSharedFromThis();
+		encryptionEngine->onServerUrlChanged(account, limeServerUrl);
 	}
 
 #else
diff --git a/src/account/account.h b/src/account/account.h
index 4f3218b9c039a700b9c3e7f5a4c30361f8781492..c82b2d71d25379ba1e282e89bdf76c62268f1ca8 100644
--- a/src/account/account.h
+++ b/src/account/account.h
@@ -41,6 +41,14 @@ typedef enum _LinphoneAccountAddressComparisonResult {
 	LinphoneAccountAddressWeakEqual
 } LinphoneAccountAddressComparisonResult;
 
+enum class LimeUserAccountStatus {
+	LimeUserAccountNone,
+	LimeUserAccountNeedCreation,
+	LimeUserAccountIsCreating,
+	LimeUserAccountCreated,
+	LimeUserAccountCreationSkiped // To send the register even if Lime user creation failed
+};
+
 class AccountCbs;
 class Address;
 class EventPublish;
@@ -78,6 +86,7 @@ public:
 	void setCustomheader(const std::string &headerName, const std::string &headerValue);
 	void setPresencePublishEvent(const std::shared_ptr<EventPublish> &presencePublishEvent);
 	void setDependency(std::shared_ptr<Account> dependency);
+	void setLimeUserAccountStatus(LimeUserAccountStatus status);
 
 	// Getters
 	int getAuthFailure() const;
@@ -95,6 +104,7 @@ public:
 	const char *getCustomHeader(const std::string &headerName) const;
 	std::shared_ptr<EventPublish> getPresencePublishEvent() const;
 	std::shared_ptr<Account> getDependency();
+	LimeUserAccountStatus getLimeUserAccountStatus() const;
 
 	int getUnreadChatMessageCount() const;
 	std::list<std::shared_ptr<AbstractChatRoom>> getChatRooms() const;
@@ -167,6 +177,7 @@ private:
 
 	int mAuthFailure;
 
+	LimeUserAccountStatus mLimeUserAccountStatus = LimeUserAccountStatus::LimeUserAccountNone;
 	bool mNeedToRegister = false;
 	bool mRegisterChanged = false;
 	bool mSendPublish = false;
diff --git a/src/c-wrapper/api/c-account.cpp b/src/c-wrapper/api/c-account.cpp
index 7e9a5d89c5fd7e43a78d221e331bab120f9a9bdb..7b794ed9e68f2ab9fec9b899bc7086f0f7e6c55a 100644
--- a/src/c-wrapper/api/c-account.cpp
+++ b/src/c-wrapper/api/c-account.cpp
@@ -36,6 +36,21 @@
 
 using namespace LinphonePrivate;
 
+bool_t linphone_account_lime_enabled(LinphoneAccount *account) {
+	auto cppAccount = Account::toCpp(account);
+	auto params = cppAccount->getAccountParams();
+	if (params) {
+		if (params->getLimeServerUrl().empty()) {
+			return FALSE;
+		}
+	} else {
+		return FALSE;
+	}
+	return (Account::toCpp(account)->getLimeUserAccountStatus() != LimeUserAccountStatus::LimeUserAccountNone &&
+	        Account::toCpp(account)->getLimeUserAccountStatus() !=
+	            LimeUserAccountStatus::LimeUserAccountCreationSkiped);
+}
+
 LinphoneAccount *linphone_account_new(LinphoneCore *lc, LinphoneAccountParams *params) {
 	return Account::createCObject(lc, AccountParams::toCpp(params)->getSharedFromThis());
 }
diff --git a/src/chat/encryption/encryption-engine.h b/src/chat/encryption/encryption-engine.h
index f9e71bb36697b04d69ef52590555997d60dd67ca..fe92754a50be44a3fd64ecd1d21ac15a23aa2627 100644
--- a/src/chat/encryption/encryption-engine.h
+++ b/src/chat/encryption/encryption-engine.h
@@ -142,7 +142,7 @@ public:
 	virtual void setTestForceDecryptionFailureFlag(BCTBX_UNUSED(bool flag)) {
 	}
 
-	virtual void onServerUrlChanged(BCTBX_UNUSED(const std::shared_ptr<Account> &account),
+	virtual void onServerUrlChanged(BCTBX_UNUSED(std::shared_ptr<Account> &account),
 	                                BCTBX_UNUSED(const std::string &limeServerUrl)) {
 	}
 
@@ -163,6 +163,9 @@ public:
 		return false;
 	}
 
+	virtual void createLimeUser(BCTBX_UNUSED(std::shared_ptr<Account> &account),
+	                            BCTBX_UNUSED(const std::string &gruu)){};
+
 protected:
 	EncryptionEngine(const std::shared_ptr<Core> &core) : CoreAccessor(core) {
 	}
diff --git a/src/chat/encryption/lime-x3dh-encryption-engine.cpp b/src/chat/encryption/lime-x3dh-encryption-engine.cpp
index b2c94a2f52f2ef111a0bd8ebd4be7681dc0a37af..7bee4e4b1801185a800cf7df11b28702ec2da84e 100644
--- a/src/chat/encryption/lime-x3dh-encryption-engine.cpp
+++ b/src/chat/encryption/lime-x3dh-encryption-engine.cpp
@@ -1002,12 +1002,17 @@ lime::limeCallback LimeX3dhEncryptionEngine::setLimeCallback(string operation) {
 }
 
 lime::limeCallback LimeX3dhEncryptionEngine::setLimeUserCreationCallback(LinphoneCore *lc,
-                                                                         const std::string localDeviceId) {
-	lime::limeCallback callback([lc, localDeviceId](lime::CallbackReturn returnCode, string info) {
+                                                                         const std::string localDeviceId,
+                                                                         shared_ptr<Account> &account) {
+	lime::limeCallback callback([lc, localDeviceId, account](lime::CallbackReturn returnCode, string info) {
 		if (returnCode == lime::CallbackReturn::success) {
 			lInfo() << "[LIME] user " << localDeviceId << " creation successful";
+			account->setLimeUserAccountStatus(LimeUserAccountStatus::LimeUserAccountCreated);
 		} else {
 			lWarning() << "[LIME] user " << localDeviceId << " creation failed with error [" << info << "]";
+			/* mLimeUserAccountStatus set to LimeUserAccountCreationSkiped in order to send the register even if Lime
+			 * user creation failed */
+			account->setLimeUserAccountStatus(LimeUserAccountStatus::LimeUserAccountCreationSkiped);
 		}
 		linphone_core_notify_imee_user_registration(lc, returnCode == lime::CallbackReturn::success,
 		                                            localDeviceId.data(), info.data());
@@ -1042,28 +1047,23 @@ void LimeX3dhEncryptionEngine::onAccountRegistrationStateChanged(std::shared_ptr
 	const std::shared_ptr<Address> &identityAddress = account->getContactAddress();
 	string localDeviceId = identityAddress->asStringUriOnly();
 
-	LinphoneCore *lc = L_GET_C_BACK_PTR(account->getCore());
 	lInfo() << "[LIME] Load lime user for device " << localDeviceId << " with server URL [" << accountLimeServerUrl
 	        << "]";
 
 	try {
-		if (!limeManager->is_user(localDeviceId)) {
-			lInfo() << "[LIME] Try to create lime user for device " << localDeviceId << " with server URL ["
-			        << accountLimeServerUrl << "]";
-			lime::limeCallback callback = setLimeUserCreationCallback(lc, localDeviceId);
-			// create user if not exist
-			limeManager->create_user(localDeviceId, accountLimeServerUrl, curve, callback);
-		} else {
+		if (limeManager->is_user(localDeviceId)) {
 			limeManager->set_x3dhServerUrl(localDeviceId, accountLimeServerUrl);
 			update(localDeviceId);
+		} else {
+			lError() << "[LIME] Lime user isn't created for device" << localDeviceId << "with server URL ["
+			         << accountLimeServerUrl << "]";
 		}
 	} catch (const exception &e) {
 		lError() << "[LIME] user for id [" << localDeviceId << "] cannot be created" << e.what();
 	}
 }
 
-void LimeX3dhEncryptionEngine::onServerUrlChanged(const std::shared_ptr<Account> &account,
-                                                  const std::string &limeServerUrl) {
+void LimeX3dhEncryptionEngine::onServerUrlChanged(std::shared_ptr<Account> &account, const std::string &limeServerUrl) {
 
 	auto accountParams = account->getAccountParams();
 	// The LIME server URL set in the account parameters is preferred to that set in the core parameters
@@ -1096,7 +1096,7 @@ void LimeX3dhEncryptionEngine::onServerUrlChanged(const std::shared_ptr<Account>
 				} else {
 					curve = lime::CurveId::c25519;
 				}
-				lime::limeCallback callback = setLimeUserCreationCallback(lc, localDeviceId);
+				lime::limeCallback callback = setLimeUserCreationCallback(lc, localDeviceId, account);
 				// create user if not exist
 				limeManager->create_user(localDeviceId, accountLimeServerUrl, curve, callback);
 			} else {
@@ -1113,4 +1113,38 @@ void LimeX3dhEncryptionEngine::setTestForceDecryptionFailureFlag(bool flag) {
 	forceFailure = flag;
 }
 
+void LimeX3dhEncryptionEngine::createLimeUser(shared_ptr<Account> &account, const string &gruu) {
+	LinphoneCore *lc = L_GET_C_BACK_PTR(account->getCore());
+	string accountLimeServerUrl = account->getAccountParams()->getLimeServerUrl();
+
+	if (accountLimeServerUrl.empty()) {
+		accountLimeServerUrl = getCore()->getX3dhServerUrl();
+		lWarning()
+		    << "[LIME] No LIME server URL in account params, trying to fallback on Core's default LIME server URL ["
+		    << accountLimeServerUrl << "]";
+	}
+	if (accountLimeServerUrl.empty()) {
+		lWarning() << "[LIME] Server URL unavailable for encryption engine: can't create user";
+		account->setLimeUserAccountStatus(LimeUserAccountStatus::LimeUserAccountCreationSkiped);
+		return;
+	}
+
+	try {
+		if (!limeManager->is_user(gruu)) {
+			lInfo() << "[LIME] Try to create lime user for device " << gruu << " with server URL ["
+			        << accountLimeServerUrl << "]";
+			lime::limeCallback callback = setLimeUserCreationCallback(lc, gruu, account);
+			// create user if not exist
+			limeManager->create_user(gruu, accountLimeServerUrl, curve, callback);
+			account->setLimeUserAccountStatus(LimeUserAccountStatus::LimeUserAccountIsCreating);
+		} else {
+			string info = "";
+			account->setLimeUserAccountStatus(LimeUserAccountStatus::LimeUserAccountCreated);
+			linphone_core_notify_imee_user_registration(lc, TRUE, gruu.data(), info.data());
+		}
+	} catch (const exception &e) {
+		lError() << "[LIME] user for id [" << gruu << "] cannot be created" << e.what();
+	}
+}
+
 LINPHONE_END_NAMESPACE
diff --git a/src/chat/encryption/lime-x3dh-encryption-engine.h b/src/chat/encryption/lime-x3dh-encryption-engine.h
index 5355026a5972c59e61bd688682dd361979d397a3..a970bf7891ee49a1191e5b7610a3ccf86bcfc985 100644
--- a/src/chat/encryption/lime-x3dh-encryption-engine.h
+++ b/src/chat/encryption/lime-x3dh-encryption-engine.h
@@ -55,7 +55,8 @@ public:
 
 	std::shared_ptr<LimeManager> getLimeManager();
 	lime::limeCallback setLimeCallback(std::string operation);
-	lime::limeCallback setLimeUserCreationCallback(LinphoneCore *lc, const std::string localDeviceId);
+	lime::limeCallback
+	setLimeUserCreationCallback(LinphoneCore *lc, const std::string localDeviceId, std::shared_ptr<Account> &account);
 	lime::CurveId getCurveId() const;
 
 	// EncryptionEngine overrides
@@ -120,7 +121,7 @@ public:
 	                                       LinphoneRegistrationState state,
 	                                       const std::string &message) override;
 
-	void onServerUrlChanged(const std::shared_ptr<Account> &account, const std::string &limeServerUrl) override;
+	void onServerUrlChanged(std::shared_ptr<Account> &account, const std::string &limeServerUrl) override;
 
 	void staleSession(const std::string localDeviceId, const std::string peerDeviceId) override;
 
@@ -140,6 +141,8 @@ public:
 	                const std::vector<uint8_t> &cipherText,
 	                std::vector<uint8_t> &plainText) const override;
 
+	void createLimeUser(std::shared_ptr<Account> &account, const std::string &gruu) override;
+
 private:
 	void update(const std::string localDeviceId);
 	std::shared_ptr<LimeManager> limeManager;
diff --git a/tester/ics-tester.cpp b/tester/ics-tester.cpp
index 7660e9ca39576a2b86fef3a443dc5d9e0a6a4f05..881d857e221cc095fb7c67872d8da1b945edc31f 100644
--- a/tester/ics-tester.cpp
+++ b/tester/ics-tester.cpp
@@ -279,18 +279,6 @@ static void send_conference_invitations(bool_t enable_encryption,
 	start_core_for_conference(coresManagerList);
 	setup_conference_info_cbs(marie);
 
-	stats initialMarieStats = marie->stat;
-	stats initialPaulineStats = pauline->stat;
-	stats initialLaureStats = laure->stat;
-
-	// Wait for lime users to be created on x3dh server
-	BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_X3dhUserCreationSuccess,
-	                             initialMarieStats.number_of_X3dhUserCreationSuccess + 1, 15000));
-	BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_X3dhUserCreationSuccess,
-	                             initialPaulineStats.number_of_X3dhUserCreationSuccess + 1, 15000));
-	BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_X3dhUserCreationSuccess,
-	                             initialLaureStats.number_of_X3dhUserCreationSuccess + 1, 15000));
-
 	// Check encryption status for all participants
 	BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(marie->lc));
 	BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(pauline->lc));
diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h
index 3395edd9e1e29b58134594903c915c8ebc835906..5127930e7d03d194c5340852cd91b38cf3e978a2 100644
--- a/tester/liblinphone_tester.h
+++ b/tester/liblinphone_tester.h
@@ -553,6 +553,8 @@ typedef struct _LinphoneCoreManager {
 	char *app_group_id;
 	void *user_info;
 	bool_t main_core;
+	bool_t skip_lime_user_creation_asserts;
+	bool_t lime_failure;
 	LinphoneCoreManagerSubscribePolicy subscribe_policy;
 	LinphoneCoreManagerPublishPolicy publish_policy;
 } LinphoneCoreManager;
@@ -602,6 +604,8 @@ LinphoneCoreManager *linphone_core_manager_create_shared(const char *rc_file,
                                                          const char *app_group_id,
                                                          bool_t main_core,
                                                          LinphoneCoreManager *mgr_to_copy);
+void linphone_core_manager_skip_lime_user_creation_asserts(LinphoneCoreManager *mgr, bool_t value);
+void linphone_core_manager_expect_lime_failure(LinphoneCoreManager *mgr, bool_t value);
 void linphone_core_manager_stop(LinphoneCoreManager *mgr);
 void linphone_core_manager_uninit_after_stop_async(LinphoneCoreManager *mgr);
 void linphone_core_manager_reinit(LinphoneCoreManager *mgr);
diff --git a/tester/lime-user-authentication-tester.cpp b/tester/lime-user-authentication-tester.cpp
index 75ec1269f872cd2a711ddea7e9fede74d5f33f8b..2577f59a7bfc7cb8f596367376a0467372c39537 100644
--- a/tester/lime-user-authentication-tester.cpp
+++ b/tester/lime-user-authentication-tester.cpp
@@ -181,17 +181,16 @@ static void TLS_mandatory_two_users(void) {
 // code readability, use name which means something instead of a list of true and false in the args
 constexpr bool tls_mandatory = true;
 constexpr bool tls_optional = false;
-constexpr bool expect_success = true;
-constexpr bool expect_failure = false;
 
 static void create_user_sip_client_cert_chain(const int curveId,
                                               const bool use_tls,
                                               const certProvider method,
                                               const std::string &cert,
                                               const std::string &key,
-                                              const bool expected_outcome,
+                                              const bool expectFailure,
                                               const std::string &username = "user_1") {
 	LinphoneCoreManager *lcm = linphone_core_manager_create(NULL);
+	linphone_core_manager_expect_lime_failure(lcm, expectFailure);
 	const std::string realm{"sip.example.org"};
 	const std::string identity = std::string("sip:").append(username).append("@").append(realm);
 
@@ -205,23 +204,11 @@ static void create_user_sip_client_cert_chain(const int curveId,
 	bctbx_list_t *coresManagerList = NULL;
 	coresManagerList = bctbx_list_append(coresManagerList, lcm);
 	set_lime_server_and_curve_list_tls(curveId, coresManagerList, TRUE, use_tls);
-	stats initialMarieStats = lcm->stat;
 
 	bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
 	start_core_for_conference(coresManagerList);
 	BC_ASSERT_TRUE(wait_for(lcm->lc, NULL, &lcm->stat.number_of_LinphoneRegistrationOk, 1));
 
-	// Wait for lime user to be created on X3DH server
-	if (expected_outcome == expect_success) {
-		BC_ASSERT_TRUE(wait_for_list(coresList, &lcm->stat.number_of_X3dhUserCreationSuccess,
-		                             initialMarieStats.number_of_X3dhUserCreationSuccess + 1,
-		                             x3dhServer_creationTimeout));
-	} else {
-		BC_ASSERT_TRUE(wait_for_list(coresList, &lcm->stat.number_of_X3dhUserCreationFailure,
-		                             initialMarieStats.number_of_X3dhUserCreationFailure + 1,
-		                             x3dhServer_creationTimeout));
-	}
-
 	bctbx_list_free(coresList);
 	bctbx_list_free(coresManagerList);
 	linphone_core_manager_destroy(lcm);
@@ -234,8 +221,8 @@ static void identity_in_altName_one_DNS_entry(void) {
 	const std::string cert_path{"certificates/client/user1_cert.pem"};
 	const std::string key_path{"certificates/client/user1_key.pem"};
 	for (const auto &certProv : availCertProv) {
-		create_user_sip_client_cert_chain(25519, tls_mandatory, certProv, cert_path, key_path, expect_success);
-		create_user_sip_client_cert_chain(448, tls_mandatory, certProv, cert_path, key_path, expect_success);
+		create_user_sip_client_cert_chain(25519, tls_mandatory, certProv, cert_path, key_path, false);
+		create_user_sip_client_cert_chain(448, tls_mandatory, certProv, cert_path, key_path, false);
 	}
 }
 
@@ -246,9 +233,8 @@ static void identity_in_subject_CN(void) {
 	const std::string cert_path{"certificates/client/user2_CN_cert.pem"};
 	const std::string key_path{"certificates/client/user2_CN_key.pem"};
 	for (const auto &certProv : availCertProv) {
-		create_user_sip_client_cert_chain(25519, tls_mandatory, certProv, cert_path, key_path, expect_success,
-		                                  "user_2");
-		create_user_sip_client_cert_chain(448, tls_mandatory, certProv, cert_path, key_path, expect_success, "user_2");
+		create_user_sip_client_cert_chain(25519, tls_mandatory, certProv, cert_path, key_path, false, "user_2");
+		create_user_sip_client_cert_chain(448, tls_mandatory, certProv, cert_path, key_path, false, "user_2");
 	}
 }
 
@@ -260,8 +246,8 @@ static void identity_in_altName_multiple_DNS_entry(void) {
 	const std::string cert_path{"certificates/client/user1_multiple_aliases_cert.pem"};
 	const std::string key_path{"certificates/client/user1_multiple_aliases_key.pem"};
 	for (const auto &certProv : availCertProv) {
-		create_user_sip_client_cert_chain(25519, tls_mandatory, certProv, cert_path, key_path, expect_success);
-		create_user_sip_client_cert_chain(448, tls_mandatory, certProv, cert_path, key_path, expect_success);
+		create_user_sip_client_cert_chain(25519, tls_mandatory, certProv, cert_path, key_path, false);
+		create_user_sip_client_cert_chain(448, tls_mandatory, certProv, cert_path, key_path, false);
 	}
 }
 
@@ -272,9 +258,8 @@ static void revoked_certificate(void) {
 	const std::string cert_path{"certificates/client/user2_revoked_cert.pem"};
 	const std::string key_path{"certificates/client/user2_revoked_key.pem"};
 	for (const auto &certProv : availCertProv) {
-		create_user_sip_client_cert_chain(25519, tls_mandatory, certProv, cert_path, key_path, expect_failure,
-		                                  "user_2");
-		create_user_sip_client_cert_chain(448, tls_mandatory, certProv, cert_path, key_path, expect_failure, "user_2");
+		create_user_sip_client_cert_chain(25519, tls_mandatory, certProv, cert_path, key_path, true, "user_2");
+		create_user_sip_client_cert_chain(448, tls_mandatory, certProv, cert_path, key_path, true, "user_2");
 	}
 }
 
@@ -286,8 +271,8 @@ static void TLS_mandatory_CN_UserId_mismatch(void) {
 	const std::string cert_path{"certificates/client/cert2.pem"};
 	const std::string key_path{"certificates/client/key2.pem"};
 	for (const auto &certProv : availCertProv) {
-		create_user_sip_client_cert_chain(25519, tls_mandatory, certProv, cert_path, key_path, expect_failure);
-		create_user_sip_client_cert_chain(448, tls_mandatory, certProv, cert_path, key_path, expect_failure);
+		create_user_sip_client_cert_chain(25519, tls_mandatory, certProv, cert_path, key_path, true);
+		create_user_sip_client_cert_chain(448, tls_mandatory, certProv, cert_path, key_path, true);
 	}
 }
 
@@ -299,8 +284,8 @@ static void TLS_optional_CN_UserId_mismatch(void) {
 	const std::string cert_path{"certificates/client/cert2.pem"};
 	const std::string key_path{"certificates/client/key2.pem"};
 	for (const auto &certProv : availCertProv) {
-		create_user_sip_client_cert_chain(25519, tls_optional, certProv, cert_path, key_path, expect_failure);
-		create_user_sip_client_cert_chain(448, tls_optional, certProv, cert_path, key_path, expect_failure);
+		create_user_sip_client_cert_chain(25519, tls_optional, certProv, cert_path, key_path, true);
+		create_user_sip_client_cert_chain(448, tls_optional, certProv, cert_path, key_path, true);
 	}
 }
 
@@ -310,8 +295,8 @@ static void TLS_optional_CN_UserId_mismatch(void) {
 static void TLS_optional_No_certificate(void) {
 	const std::string empty{};
 	/* just use the config_sip method, each method shall actually just do nothing when given an empty certificate */
-	create_user_sip_client_cert_chain(25519, tls_optional, certProvider::config_sip, empty, empty, expect_success);
-	create_user_sip_client_cert_chain(448, tls_optional, certProvider::config_sip, empty, empty, expect_success);
+	create_user_sip_client_cert_chain(25519, tls_optional, certProvider::config_sip, empty, empty, false);
+	create_user_sip_client_cert_chain(448, tls_optional, certProvider::config_sip, empty, empty, false);
 }
 
 /**
@@ -320,8 +305,8 @@ static void TLS_optional_No_certificate(void) {
 static void TLS_mandatory_No_certificate(void) {
 	const std::string empty{};
 	/* just use the config_sip method, each method shall actually just do nothing when given an empty certificate */
-	create_user_sip_client_cert_chain(25519, tls_mandatory, certProvider::config_sip, empty, empty, expect_failure);
-	create_user_sip_client_cert_chain(448, tls_mandatory, certProvider::config_sip, empty, empty, expect_failure);
+	create_user_sip_client_cert_chain(25519, tls_mandatory, certProvider::config_sip, empty, empty, true);
+	create_user_sip_client_cert_chain(448, tls_mandatory, certProvider::config_sip, empty, empty, true);
 }
 
 static void local_set_lime_server_and_curve(LinphoneCoreManager *manager, const char *curve, const char *server) {
@@ -438,6 +423,7 @@ const char *wrong_lime_server = "https://lime.wildcard8.linphone.org:8443/lime-s
 
 static void invalid_lime_server_in_account_curve(const int curveId) {
 	LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
+	linphone_core_manager_skip_lime_user_creation_asserts(marie, TRUE);
 	bctbx_list_t *coresManagerList = NULL;
 	coresManagerList = bctbx_list_append(coresManagerList, marie);
 
diff --git a/tester/local_chat_imdn_tester.cpp b/tester/local_chat_imdn_tester.cpp
index e408eee728dd2cffd557fda9cd5454817c7d4586..f4362cd301ab11c7962861c99a6cbf016fe82ec9 100644
--- a/tester/local_chat_imdn_tester.cpp
+++ b/tester/local_chat_imdn_tester.cpp
@@ -264,20 +264,6 @@ group_chat_room_with_client_idmn_after_restart_base(bool_t encrypted, bool_t add
 		coresList = bctbx_list_append(coresList, michelle2.getLc());
 
 		if (encrypted) {
-			BC_ASSERT_TRUE(wait_for_list(coresList, &marie.getStats().number_of_X3dhUserCreationSuccess,
-			                             marie_stat.number_of_X3dhUserCreationSuccess + 1, x3dhServer_creationTimeout));
-			BC_ASSERT_TRUE(wait_for_list(coresList, &laure.getStats().number_of_X3dhUserCreationSuccess,
-			                             laure_stat.number_of_X3dhUserCreationSuccess + 1, x3dhServer_creationTimeout));
-			BC_ASSERT_TRUE(wait_for_list(coresList, &pauline.getStats().number_of_X3dhUserCreationSuccess,
-			                             pauline_stat.number_of_X3dhUserCreationSuccess + 1,
-			                             x3dhServer_creationTimeout));
-			BC_ASSERT_TRUE(wait_for_list(coresList, &michelle.getStats().number_of_X3dhUserCreationSuccess,
-			                             michelle_stat.number_of_X3dhUserCreationSuccess + 1,
-			                             x3dhServer_creationTimeout));
-			BC_ASSERT_TRUE(wait_for_list(coresList, &michelle2.getStats().number_of_X3dhUserCreationSuccess,
-			                             michelle2_stat.number_of_X3dhUserCreationSuccess + 1,
-			                             x3dhServer_creationTimeout));
-
 			BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(marie.getLc()));
 			BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(pauline.getLc()));
 			BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(laure.getLc()));
@@ -365,9 +351,6 @@ group_chat_room_with_client_idmn_after_restart_base(bool_t encrypted, bool_t add
 		coresList = bctbx_list_append(coresList, berthe.getLc());
 
 		if (encrypted) {
-			BC_ASSERT_TRUE(wait_for_list(coresList, &berthe.getStats().number_of_X3dhUserCreationSuccess,
-			                             berthe_stat.number_of_X3dhUserCreationSuccess + 1,
-			                             x3dhServer_creationTimeout));
 			BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(berthe.getLc()));
 		}
 
@@ -716,13 +699,6 @@ static void group_chat_room_lime_session_corrupted(void) {
 		coresList = bctbx_list_append(coresList, pauline.getLc());
 		coresList = bctbx_list_append(coresList, laure.getLc());
 
-		BC_ASSERT_TRUE(wait_for_list(coresList, &marie.getStats().number_of_X3dhUserCreationSuccess,
-		                             marie_stat.number_of_X3dhUserCreationSuccess + 1, x3dhServer_creationTimeout));
-		BC_ASSERT_TRUE(wait_for_list(coresList, &laure.getStats().number_of_X3dhUserCreationSuccess,
-		                             laure_stat.number_of_X3dhUserCreationSuccess + 1, x3dhServer_creationTimeout));
-		BC_ASSERT_TRUE(wait_for_list(coresList, &pauline.getStats().number_of_X3dhUserCreationSuccess,
-		                             pauline_stat.number_of_X3dhUserCreationSuccess + 1, x3dhServer_creationTimeout));
-
 		BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(marie.getLc()));
 		BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(pauline.getLc()));
 		BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(laure.getLc()));
diff --git a/tester/local_conference_tester_functions.cpp b/tester/local_conference_tester_functions.cpp
index 58f0b080b1d374cd7e59faf9cbb6a684a051885c..a50c6636b60fa2a68bdf9a9766a3e1dac91c9f31 100644
--- a/tester/local_conference_tester_functions.cpp
+++ b/tester/local_conference_tester_functions.cpp
@@ -299,18 +299,6 @@ void group_chat_room_with_client_restart_base(bool encrypted) {
 		stats initialLaureStats = laure.getStats();
 
 		if (encrypted) {
-			BC_ASSERT_TRUE(wait_for_list(coresList, &marie.getStats().number_of_X3dhUserCreationSuccess,
-			                             initialMarieStats.number_of_X3dhUserCreationSuccess + 1,
-			                             x3dhServer_creationTimeout));
-			BC_ASSERT_TRUE(wait_for_list(coresList, &michelle.getStats().number_of_X3dhUserCreationSuccess,
-			                             initialMichelleStats.number_of_X3dhUserCreationSuccess + 1,
-			                             x3dhServer_creationTimeout));
-			BC_ASSERT_TRUE(wait_for_list(coresList, &berthe.getStats().number_of_X3dhUserCreationSuccess,
-			                             initialBertheStats.number_of_X3dhUserCreationSuccess + 1,
-			                             x3dhServer_creationTimeout));
-			BC_ASSERT_TRUE(wait_for_list(coresList, &laure.getStats().number_of_X3dhUserCreationSuccess,
-			                             initialLaureStats.number_of_X3dhUserCreationSuccess + 1,
-			                             x3dhServer_creationTimeout));
 			BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(marie.getLc()));
 			BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(michelle.getLc()));
 			BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(berthe.getLc()));
@@ -381,9 +369,6 @@ void group_chat_room_with_client_restart_base(bool encrypted) {
 		stats initialMichelle2Stats = michelle2.getStats();
 		coresList = bctbx_list_append(coresList, michelle2.getLc());
 		if (encrypted) {
-			BC_ASSERT_TRUE(wait_for_list(coresList, &michelle2.getStats().number_of_X3dhUserCreationSuccess,
-			                             initialMichelle2Stats.number_of_X3dhUserCreationSuccess + 1,
-			                             x3dhServer_creationTimeout));
 			BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(michelle2.getLc()));
 		}
 
@@ -672,25 +657,6 @@ void group_chat_room_with_sip_errors_base(bool invite_error, bool subscribe_erro
 		coresList = bctbx_list_append(coresList, berthe.getLc());
 
 		if (encrypted) {
-			BC_ASSERT_TRUE(wait_for_list(coresList, &marie.getStats().number_of_X3dhUserCreationSuccess,
-			                             initialMarieStats.number_of_X3dhUserCreationSuccess + 1,
-			                             x3dhServer_creationTimeout));
-			BC_ASSERT_TRUE(wait_for_list(coresList, &pauline.getStats().number_of_X3dhUserCreationSuccess,
-			                             initialPaulineStats.number_of_X3dhUserCreationSuccess + 1,
-			                             x3dhServer_creationTimeout));
-			BC_ASSERT_TRUE(wait_for_list(coresList, &michelle.getStats().number_of_X3dhUserCreationSuccess,
-			                             initialMichelleStats.number_of_X3dhUserCreationSuccess + 1,
-			                             x3dhServer_creationTimeout));
-			BC_ASSERT_TRUE(wait_for_list(coresList, &michelle2.getStats().number_of_X3dhUserCreationSuccess,
-			                             initialMichelle2Stats.number_of_X3dhUserCreationSuccess + 1,
-			                             x3dhServer_creationTimeout));
-			BC_ASSERT_TRUE(wait_for_list(coresList, &laure.getStats().number_of_X3dhUserCreationSuccess,
-			                             initialLaureStats.number_of_X3dhUserCreationSuccess + 1,
-			                             x3dhServer_creationTimeout));
-			BC_ASSERT_TRUE(wait_for_list(coresList, &berthe.getStats().number_of_X3dhUserCreationSuccess,
-			                             initialBertheStats.number_of_X3dhUserCreationSuccess + 1,
-			                             x3dhServer_creationTimeout));
-
 			BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(marie.getLc()));
 			BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(pauline.getLc()));
 			BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(laure.getLc()));
@@ -1271,14 +1237,6 @@ void group_chat_room_lime_server_message(bool encrypted) {
 		if (encrypted) {
 			auto rawEncryptionSuccess = 0;
 
-			BC_ASSERT_TRUE(wait_for_list(coresList, &marie.getStats().number_of_X3dhUserCreationSuccess,
-			                             marie_stat.number_of_X3dhUserCreationSuccess + 1, x3dhServer_creationTimeout));
-			BC_ASSERT_TRUE(wait_for_list(coresList, &laure.getStats().number_of_X3dhUserCreationSuccess,
-			                             laure_stat.number_of_X3dhUserCreationSuccess + 1, x3dhServer_creationTimeout));
-			BC_ASSERT_TRUE(wait_for_list(coresList, &pauline.getStats().number_of_X3dhUserCreationSuccess,
-			                             pauline_stat.number_of_X3dhUserCreationSuccess + 1,
-			                             x3dhServer_creationTimeout));
-
 			BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(marie.getLc()));
 			BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(pauline.getLc()));
 			BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(laure.getLc()));
@@ -1413,12 +1371,6 @@ void one_to_one_group_chat_room_deletion_by_server_client_base(bool encrypted) {
 		coresList = bctbx_list_append(coresList, pauline.getLc());
 
 		if (encrypted) {
-			BC_ASSERT_TRUE(wait_for_list(coresList, &marie.getStats().number_of_X3dhUserCreationSuccess,
-			                             marie_stat.number_of_X3dhUserCreationSuccess + 1, x3dhServer_creationTimeout));
-			BC_ASSERT_TRUE(wait_for_list(coresList, &pauline.getStats().number_of_X3dhUserCreationSuccess,
-			                             pauline_stat.number_of_X3dhUserCreationSuccess + 1,
-			                             x3dhServer_creationTimeout));
-
 			BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(marie.getLc()));
 			BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(pauline.getLc()));
 		}
diff --git a/tester/local_secure_chat_tester.cpp b/tester/local_secure_chat_tester.cpp
index dcdbdaece793f2584eaa17c7cf170359086d0a78..dda3865fba45ea313fb1740fe7065d5853f14942 100644
--- a/tester/local_secure_chat_tester.cpp
+++ b/tester/local_secure_chat_tester.cpp
@@ -56,19 +56,6 @@ static void secure_group_chat_room_with_chat_room_deleted_before_server_restart(
 		coresList = bctbx_list_append(coresList, michelle.getLc());
 		coresList = bctbx_list_append(coresList, michelle2.getLc());
 
-		BC_ASSERT_TRUE(wait_for_list(coresList, &marie.getStats().number_of_X3dhUserCreationSuccess,
-		                             initialMarieStats.number_of_X3dhUserCreationSuccess + 1,
-		                             x3dhServer_creationTimeout));
-		BC_ASSERT_TRUE(wait_for_list(coresList, &marie2.getStats().number_of_X3dhUserCreationSuccess,
-		                             initialMarie2Stats.number_of_X3dhUserCreationSuccess + 1,
-		                             x3dhServer_creationTimeout));
-		BC_ASSERT_TRUE(wait_for_list(coresList, &michelle.getStats().number_of_X3dhUserCreationSuccess,
-		                             initialMichelleStats.number_of_X3dhUserCreationSuccess + 1,
-		                             x3dhServer_creationTimeout));
-		BC_ASSERT_TRUE(wait_for_list(coresList, &michelle2.getStats().number_of_X3dhUserCreationSuccess,
-		                             initialMichelle2Stats.number_of_X3dhUserCreationSuccess + 1,
-		                             x3dhServer_creationTimeout));
-
 		BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(marie.getLc()));
 		BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(marie2.getLc()));
 		BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(michelle.getLc()));
diff --git a/tester/tester.c b/tester/tester.c
index f7f5c90712f088b9604787fe4b296fdfcb7697e4..66ff19d93d9593b48b83dff9268f7e729bd8b007 100644
--- a/tester/tester.c
+++ b/tester/tester.c
@@ -2605,10 +2605,32 @@ void linphone_core_manager_start(LinphoneCoreManager *mgr, bool_t check_for_prox
 	}
 
 	if (proxy_count) {
+		const bctbx_list_t *accounts = linphone_core_get_account_list(mgr->lc);
+		int lime_enabled = 0;
+		for (const bctbx_list_t *account_it = accounts; account_it != NULL; account_it = account_it->next) {
+			LinphoneAccount *account = (LinphoneAccount *)(bctbx_list_get_data(account_it));
+			if (linphone_account_lime_enabled(account)) {
+				lime_enabled++;
+			}
+		}
+		if (lime_enabled != 0 && !mgr->skip_lime_user_creation_asserts) {
+			// Wait for lime users to be created on X3DH server
+			if (mgr->lime_failure) {
+				BC_ASSERT_TRUE(wait_for_until(mgr->lc, NULL, &mgr->stat.number_of_X3dhUserCreationFailure,
+				                              mgr->stat.number_of_X3dhUserCreationFailure + 1,
+				                              x3dhServer_creationTimeout));
+			} else {
+				BC_ASSERT_TRUE(wait_for_until(mgr->lc, NULL, &mgr->stat.number_of_X3dhUserCreationSuccess,
+				                              mgr->stat.number_of_X3dhUserCreationSuccess + lime_enabled,
+				                              x3dhServer_creationTimeout));
+			}
+			// At most the number of accounts that don't have lime enabled were able to register
+			BC_ASSERT_LOWER(mgr->stat.number_of_LinphoneRegistrationOk,
+			                old_registration_ok + (proxy_count - lime_enabled), int, "%d");
+		}
 #define REGISTER_TIMEOUT 20 /* seconds */
 		int success = wait_for_until(mgr->lc, NULL, &mgr->stat.number_of_LinphoneRegistrationOk,
-		                             mgr->stat.number_of_LinphoneRegistrationOk + proxy_count,
-		                             (REGISTER_TIMEOUT * 1000 * proxy_count));
+		                             old_registration_ok + proxy_count, (REGISTER_TIMEOUT * 1000 * proxy_count));
 		if (!success) {
 			ms_error("Did not register after %d seconds for %d proxies", REGISTER_TIMEOUT, proxy_count);
 		}
@@ -2727,6 +2749,14 @@ LinphoneCoreManager *linphone_core_manager_create_shared(const char *rc_file,
 	return manager;
 }
 
+void linphone_core_manager_skip_lime_user_creation_asserts(LinphoneCoreManager *mgr, bool_t value) {
+	mgr->skip_lime_user_creation_asserts = value;
+}
+
+void linphone_core_manager_expect_lime_failure(LinphoneCoreManager *mgr, bool_t value) {
+	mgr->lime_failure = value;
+}
+
 static void check_orphan_nat_policy_section(LinphoneCoreManager *mgr) {
 	bctbx_list_t *l = linphone_config_get_sections_names_list(linphone_core_get_config(mgr->lc));
 	bctbx_list_t *elem;