diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c
index 49c0f0f9b8980c3616448d812127aa6f5bee8424..0017d786ceca7c3cc0ba9f06c63502c279a49248 100644
--- a/coreapi/callbacks.c
+++ b/coreapi/callbacks.c
@@ -812,12 +812,9 @@ static void message_delivery_update(SalOp *op, SalMessageDeliveryStatus status)
 	auto chatRoom = msg->getChatRoom();
 	// Check that the message does not belong to an already destroyed chat room - if so, do not invoke callbacks
 	if (chatRoom) {
-		// It would be better to call setParticipantState but doing so, it causes a memory leak
-		L_GET_PRIVATE(msg)->setState((LinphonePrivate::ChatMessage::State)chatStatusSal2Linphone(status));
-		/*L_GET_PRIVATE(msg)->setParticipantState(chatRoom->getMe()->getAddress(),
+		L_GET_PRIVATE(msg)->setParticipantState(chatRoom->getMe()->getAddress(),
 		                                        (LinphonePrivate::ChatMessage::State)chatStatusSal2Linphone(status),
 		                                        ::ms_time(NULL));
-		*/
 	}
 }
 
diff --git a/src/chat/chat-message/chat-message-p.h b/src/chat/chat-message/chat-message-p.h
index a8f66f7e944ae51ae5e1f04058cd2928f66da09a..40691e961d72e36b89a46fab4a886b90bdb6cee4 100644
--- a/src/chat/chat-message/chat-message-p.h
+++ b/src/chat/chat-message/chat-message-p.h
@@ -250,9 +250,6 @@ public:
 
 	long long storageId = -1;
 
-	// It should be private if we do so, but it must be called in message_delivery_update to avoid a memory leak
-	virtual void setState(ChatMessage::State newState);
-
 protected:
 	bool displayNotificationRequired = true;
 	bool negativeDeliveryNotificationRequired = true;
@@ -261,6 +258,9 @@ protected:
 	std::string contentEncoding;
 
 private:
+	// Keep setState private as the chat message state must only be set through setParticipantState
+	virtual void setState(ChatMessage::State newState);
+
 	ChatMessagePrivate(const std::shared_ptr<AbstractChatRoom> &cr, ChatMessage::Direction dir);
 	virtual ~ChatMessagePrivate();
 
diff --git a/src/chat/chat-message/chat-message.cpp b/src/chat/chat-message/chat-message.cpp
index b58e442d284ca3d6e670230dfa8ebeedaf43e508..f9bff5e34b6c14deca721cfdbd7251c3956adf1a 100644
--- a/src/chat/chat-message/chat-message.cpp
+++ b/src/chat/chat-message/chat-message.cpp
@@ -157,6 +157,8 @@ void ChatMessagePrivate::setParticipantState(const std::shared_ptr<Address> &par
 
 	// Send IMDN if the participant whose state changes is me
 	if (isMe) {
+		lInfo() << __func__ << " DEBUG DEBUG me message " << q << " state changed to " << Utils::toString(newState)
+		        << " is valid " << q->isValid() << " is reaction " << q->isReaction() << " to be stored " << toBeStored;
 		switch (newState) {
 			case ChatMessage::State::Displayed:
 				static_cast<ChatRoomPrivate *>(chatRoom->getPrivate())->sendDisplayNotification(sharedMessage);
@@ -175,7 +177,7 @@ void ChatMessagePrivate::setParticipantState(const std::shared_ptr<Address> &par
 		}
 	}
 
-	if (!q->isValid()) {
+	if (!q->isValid() && (eventLog || (newState == ChatMessage::State::NotDelivered))) {
 		if (newState == ChatMessage::State::NotDelivered) {
 			setState(newState);
 		}
@@ -212,7 +214,9 @@ void ChatMessagePrivate::setParticipantState(const std::shared_ptr<Address> &par
 
 	lInfo() << "Chat message " << sharedMessage << ": moving participant '" << *participantAddress << "' state to "
 	        << Utils::toString(newState);
-	mainDb->setChatMessageParticipantState(eventLog, participantAddress, newState, stateChangeTime);
+	if (eventLog) {
+		mainDb->setChatMessageParticipantState(eventLog, participantAddress, newState, stateChangeTime);
+	}
 
 	// Update chat message state if it doesn't depend on IMDN
 	if (isMe && !isImdnControlledState(newState)) {
@@ -305,7 +309,13 @@ void ChatMessagePrivate::setState(ChatMessage::State newState) {
 			// participants being part of the chatroom
 			for (const auto &imdnState : q->getParticipantsState()) {
 				const auto &participant = imdnState.getParticipant();
-				setParticipantState(participant->getAddress(), state, q->getTime());
+				const auto &participantAddress = participant->getAddress();
+				auto me = chatRoom->getMe();
+				const auto isMe = participantAddress->weakEqual(*me->getAddress());
+				// me participant was already set to Delivered by function message_delivery_update
+				if (!isMe) {
+					setParticipantState(participantAddress, state, q->getTime());
+				}
 			}
 		}
 
@@ -1358,7 +1368,6 @@ void ChatMessagePrivate::send() {
 	/* If operation failed, we should not change message state */
 	if (direction == ChatMessage::Direction::Outgoing) {
 		setIsReadOnly(true);
-		setParticipantState(chatRoom->getMe()->getAddress(), ChatMessage::State::InProgress, ::ms_time(nullptr));
 	}
 
 	if (q->isReaction()) {