diff --git a/CHANGES.md b/CHANGES.md
index 76da7609e1..79ea40de59 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -8,7 +8,7 @@ Improvements 🙌:
  -
 
 Bugfix 🐛:
- -
+ - Fix issue when updating the avatar of a room
 
 Translations 🗣:
  -
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt
index 75c7ad4d53..a81f503e77 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt
@@ -555,7 +555,7 @@ class SASTest : InstrumentedTest {
 
         mTestHelper.waitWithLatch {
             mTestHelper.retryPeriodicallyWithLatch(it) {
-                val prAlicePOV = aliceVerificationService.getExistingVerificationRequest(bobSession.myUserId)?.firstOrNull()
+                val prAlicePOV = aliceVerificationService.getExistingVerificationRequests(bobSession.myUserId).firstOrNull()
                 requestID = prAlicePOV?.transactionId
                 Log.v("TEST", "== alicePOV is $prAlicePOV")
                 prAlicePOV?.transactionId != null && prAlicePOV.localId == req.localId
@@ -566,7 +566,7 @@ class SASTest : InstrumentedTest {
 
         mTestHelper.waitWithLatch {
             mTestHelper.retryPeriodicallyWithLatch(it) {
-                val prBobPOV = bobVerificationService.getExistingVerificationRequest(aliceSession.myUserId)?.firstOrNull()
+                val prBobPOV = bobVerificationService.getExistingVerificationRequests(aliceSession.myUserId).firstOrNull()
                 Log.v("TEST", "== prBobPOV is $prBobPOV")
                 prBobPOV?.transactionId == requestID
             }
@@ -581,7 +581,7 @@ class SASTest : InstrumentedTest {
         // wait for alice to get the ready
         mTestHelper.waitWithLatch {
             mTestHelper.retryPeriodicallyWithLatch(it) {
-                val prAlicePOV = aliceVerificationService.getExistingVerificationRequest(bobSession.myUserId)?.firstOrNull()
+                val prAlicePOV = aliceVerificationService.getExistingVerificationRequests(bobSession.myUserId).firstOrNull()
                 Log.v("TEST", "== prAlicePOV is $prAlicePOV")
                 prAlicePOV?.transactionId == requestID && prAlicePOV?.isReady != null
             }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt
index 65c6a1f1f7..2413786ea9 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt
@@ -41,7 +41,7 @@ interface VerificationService {
 
     fun getExistingTransaction(otherUserId: String, tid: String): VerificationTransaction?
 
-    fun getExistingVerificationRequest(otherUserId: String): List<PendingVerificationRequest>?
+    fun getExistingVerificationRequests(otherUserId: String): List<PendingVerificationRequest>
 
     fun getExistingVerificationRequest(otherUserId: String, tid: String?): PendingVerificationRequest?
 
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt
index 7f02750359..29ddd92213 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt
@@ -537,11 +537,10 @@ internal class DefaultVerificationService @Inject constructor(
                     // If there is a corresponding request, we can auto accept
                     // as we are the one requesting in first place (or we accepted the request)
                     // I need to check if the pending request was related to this device also
-                    val autoAccept = getExistingVerificationRequest(otherUserId)?.any {
+                    val autoAccept = getExistingVerificationRequests(otherUserId).any {
                         it.transactionId == startReq.transactionId
                                 && (it.requestInfo?.fromDevice == this.deviceId || it.readyInfo?.fromDevice == this.deviceId)
                     }
-                            ?: false
                     val tx = DefaultIncomingSASDefaultVerificationTransaction(
 //                            this,
                             setDeviceVerificationAction,
@@ -837,8 +836,8 @@ internal class DefaultVerificationService @Inject constructor(
             // SAS do not care for now?
         }
 
-        // Now transactions are udated, let's also update Requests
-        val existingRequest = getExistingVerificationRequest(senderId)?.find { it.transactionId == doneReq.transactionId }
+        // Now transactions are updated, let's also update Requests
+        val existingRequest = getExistingVerificationRequests(senderId).find { it.transactionId == doneReq.transactionId }
         if (existingRequest == null) {
             Timber.e("## SAS Received Done for unknown request txId:${doneReq.transactionId}")
             return
@@ -892,7 +891,7 @@ internal class DefaultVerificationService @Inject constructor(
     private fun handleReadyReceived(senderId: String,
                                     readyReq: ValidVerificationInfoReady,
                                     transportCreator: (DefaultVerificationTransaction) -> VerificationTransport) {
-        val existingRequest = getExistingVerificationRequest(senderId)?.find { it.transactionId == readyReq.transactionId }
+        val existingRequest = getExistingVerificationRequests(senderId).find { it.transactionId == readyReq.transactionId }
         if (existingRequest == null) {
             Timber.e("## SAS Received Ready for unknown request txId:${readyReq.transactionId} fromDevice ${readyReq.fromDevice}")
             return
@@ -1041,9 +1040,9 @@ internal class DefaultVerificationService @Inject constructor(
         }
     }
 
-    override fun getExistingVerificationRequest(otherUserId: String): List<PendingVerificationRequest>? {
+    override fun getExistingVerificationRequests(otherUserId: String): List<PendingVerificationRequest> {
         synchronized(lock = pendingRequests) {
-            return pendingRequests[otherUserId]
+            return pendingRequests[otherUserId].orEmpty()
         }
     }
 
diff --git a/multipicker/src/main/java/im/vector/lib/multipicker/CameraPicker.kt b/multipicker/src/main/java/im/vector/lib/multipicker/CameraPicker.kt
index 3f24a28c28..64df788e53 100644
--- a/multipicker/src/main/java/im/vector/lib/multipicker/CameraPicker.kt
+++ b/multipicker/src/main/java/im/vector/lib/multipicker/CameraPicker.kt
@@ -94,19 +94,21 @@ class CameraPicker {
         return Intent(MediaStore.ACTION_IMAGE_CAPTURE)
     }
 
-    private fun createPhotoUri(context: Context): Uri {
-        val file = createImageFile(context)
-        val authority = context.packageName + ".multipicker.fileprovider"
-        return FileProvider.getUriForFile(context, authority, file)
-    }
+    companion object {
+        fun createPhotoUri(context: Context): Uri {
+            val file = createImageFile(context)
+            val authority = context.packageName + ".multipicker.fileprovider"
+            return FileProvider.getUriForFile(context, authority, file)
+        }
 
-    private fun createImageFile(context: Context): File {
-        val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
-        val storageDir: File = context.filesDir
-        return File.createTempFile(
-                "${timeStamp}_", /* prefix */
-                ".jpg", /* suffix */
-                storageDir /* directory */
-        )
+        private fun createImageFile(context: Context): File {
+            val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
+            val storageDir: File = context.filesDir
+            return File.createTempFile(
+                    "${timeStamp}_", /* prefix */
+                    ".jpg", /* suffix */
+                    storageDir /* directory */
+            )
+        }
     }
 }
diff --git a/vector/src/main/java/im/vector/app/core/dialogs/GalleryOrCameraDialogHelper.kt b/vector/src/main/java/im/vector/app/core/dialogs/GalleryOrCameraDialogHelper.kt
index 7198cdb4a2..8cb122d5bb 100644
--- a/vector/src/main/java/im/vector/app/core/dialogs/GalleryOrCameraDialogHelper.kt
+++ b/vector/src/main/java/im/vector/app/core/dialogs/GalleryOrCameraDialogHelper.kt
@@ -23,6 +23,7 @@ import androidx.core.net.toUri
 import androidx.fragment.app.Fragment
 import com.yalantis.ucrop.UCrop
 import im.vector.app.R
+import im.vector.app.core.extensions.insertBeforeLast
 import im.vector.app.core.extensions.registerStartForActivityResult
 import im.vector.app.core.resources.ColorProvider
 import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO
@@ -86,7 +87,7 @@ class GalleryOrCameraDialogHelper(
     }
 
     private fun startUCrop(image: MultiPickerImageType) {
-        val destinationFile = File(activity.cacheDir, "${image.displayName}_e_${System.currentTimeMillis()}")
+        val destinationFile = File(activity.cacheDir, image.displayName.insertBeforeLast("_e_${System.currentTimeMillis()}"))
         val uri = image.contentUri
         createUCropWithDefaultSettings(colorProvider, uri, destinationFile.toUri(), fragment.getString(R.string.rotate_and_crop_screen_title))
                 .withAspectRatio(1f, 1f)
@@ -116,7 +117,7 @@ class GalleryOrCameraDialogHelper(
         when (type) {
             Type.Camera ->
                 if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, activity, takePhotoPermissionActivityResultLauncher)) {
-                    avatarCameraUri = MultiPicker.get(MultiPicker.CAMERA).startWithExpectingFile(activity, takePhotoActivityResultLauncher)
+                    doOpenCamera()
                 }
             Type.Gallery ->
                 MultiPicker.get(MultiPicker.IMAGE).single().startWith(pickImageActivityResultLauncher)
diff --git a/vector/src/main/java/im/vector/app/core/extensions/BasicExtensions.kt b/vector/src/main/java/im/vector/app/core/extensions/BasicExtensions.kt
index c3e6520a46..07a684abef 100644
--- a/vector/src/main/java/im/vector/app/core/extensions/BasicExtensions.kt
+++ b/vector/src/main/java/im/vector/app/core/extensions/BasicExtensions.kt
@@ -48,3 +48,21 @@ fun CharSequence.isMsisdn(): Boolean {
         false
     }
 }
+
+/**
+ * Useful to append a String at the end of a filename but before the extension if any
+ * Ex:
+ * - "file.txt".insertBeforeLast("_foo") will return "file_foo.txt"
+ * - "file".insertBeforeLast("_foo") will return "file_foo"
+ * - "fi.le.txt".insertBeforeLast("_foo") will return "fi.le_foo.txt"
+ * - null.insertBeforeLast("_foo") will return "_foo"
+ */
+fun String?.insertBeforeLast(insert: String, delimiter: String = ".") : String {
+    if (this == null) return insert
+    val idx = lastIndexOf(delimiter)
+    return if (idx == -1) {
+        this + insert
+    } else {
+        replaceRange(idx, idx, insert)
+    }
+}
diff --git a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewFragment.kt b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewFragment.kt
index 9f3ba39bbe..ba0250724c 100644
--- a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewFragment.kt
@@ -38,6 +38,7 @@ import com.airbnb.mvrx.withState
 import com.yalantis.ucrop.UCrop
 import im.vector.app.R
 import im.vector.app.core.extensions.cleanup
+import im.vector.app.core.extensions.insertBeforeLast
 import im.vector.app.core.extensions.registerStartForActivityResult
 import im.vector.app.core.platform.VectorBaseFragment
 import im.vector.app.core.resources.ColorProvider
@@ -170,7 +171,7 @@ class AttachmentsPreviewFragment @Inject constructor(
 
     private fun handleEditAction() = withState(viewModel) {
         val currentAttachment = it.attachments.getOrNull(it.currentAttachmentIndex) ?: return@withState
-        val destinationFile = File(requireContext().cacheDir, "${currentAttachment.name}_edited_image_${System.currentTimeMillis()}")
+        val destinationFile = File(requireContext().cacheDir, currentAttachment.name.insertBeforeLast("_edited_image_${System.currentTimeMillis()}"))
         val uri = currentAttachment.queryUri
         createUCropWithDefaultSettings(colorProvider, uri, destinationFile.toUri(), currentAttachment.name)
                 .getIntent(requireContext())
diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt
index 951ff4ede6..c7533cd3df 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt
@@ -140,6 +140,12 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
     }
 
     private fun handleDoResetAll() {
+        // as we are going to reset, we'd better cancel all outgoing requests
+        // if not they could be accepted in the middle of the reset process
+        // and cause strange use cases
+        session.cryptoService().verificationService().getExistingVerificationRequests(session.myUserId).forEach {
+            session.cryptoService().verificationService().cancelVerificationRequest(it)
+        }
         _viewEvents.post(SharedSecureStorageViewEvent.ShowResetBottomSheet)
     }
 
diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt
index b7c689f41f..47e373ed0a 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt
@@ -237,7 +237,7 @@ class BootstrapCrossSigningTask @Inject constructor(
             Timber.d("## BootstrapCrossSigningTask: Creating 4S - Checking megolm backup")
 
             // First ensure that in sync
-            val serverVersion = awaitCallback<KeysVersionResult?> {
+            var serverVersion = awaitCallback<KeysVersionResult?> {
                 session.cryptoService().keysBackupService().getCurrentVersion(it)
             }
 
@@ -247,6 +247,16 @@ class BootstrapCrossSigningTask @Inject constructor(
                     || (params.setupMode == SetupMode.PASSPHRASE_AND_NEEDED_SECRETS_RESET && !isMegolmBackupSecretKnown)
                     || (params.setupMode == SetupMode.HARD_RESET)
             if (shouldCreateKeyBackup) {
+                // clear all existing backups
+                while (serverVersion != null) {
+                    awaitCallback<Unit> {
+                        session.cryptoService().keysBackupService().deleteBackup(serverVersion!!.version, it)
+                    }
+                    serverVersion = awaitCallback {
+                        session.cryptoService().keysBackupService().getCurrentVersion(it)
+                    }
+                }
+
                 Timber.d("## BootstrapCrossSigningTask: Creating 4S - Create megolm backup")
                 val creationInfo = awaitCallback<MegolmBackupCreationInfo> {
                     session.cryptoService().keysBackupService().prepareKeysBackupVersion(null, null, it)
diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt
index e42eb6de6f..7d98b7c2a5 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt
@@ -164,7 +164,7 @@ class IncomingVerificationRequestHandler @Inject constructor(
 
     override fun verificationRequestUpdated(pr: PendingVerificationRequest) {
         // If an incoming request is readied (by another device?) we should discard the alert
-        if (pr.isIncoming && (pr.isReady || pr.handledByOtherSession)) {
+        if (pr.isIncoming && (pr.isReady || pr.handledByOtherSession || pr.cancelConclusion != null)) {
             popupAlertManager.cancelAlert(uniqueIdForVerificationRequest(pr))
         }
     }
diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt
index 2d09974687..aa20a9a992 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt
@@ -99,8 +99,8 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
         val pr = if (selfVerificationMode) {
             // See if active tx for this user and take it
 
-            session.cryptoService().verificationService().getExistingVerificationRequest(args.otherUserId)
-                    ?.lastOrNull { !it.isFinished }
+            session.cryptoService().verificationService().getExistingVerificationRequests(args.otherUserId)
+                    .lastOrNull { !it.isFinished }
                     ?.also { verificationRequest ->
                         if (verificationRequest.isIncoming && !verificationRequest.isReady) {
                             // auto ready in this case, as we are waiting
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt
index 32d8f043c3..6bf88e755e 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt
@@ -153,20 +153,20 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
     }
 
     private fun handleSetAvatarAction(action: RoomSettingsAction.SetAvatarAction) {
-        deletePendingAvatar()
-        setState { copy(avatarAction = action.avatarAction) }
-    }
-
-    private fun deletePendingAvatar() {
-        // Maybe delete the pending avatar
-        withState {
-            (it.avatarAction as? RoomSettingsViewState.AvatarAction.UpdateAvatar)
-                    ?.let { tryOrNull { it.newAvatarUri.toFile().delete() } }
+        setState {
+            deletePendingAvatar(this)
+            copy(avatarAction = action.avatarAction)
         }
     }
 
+    private fun deletePendingAvatar(state: RoomSettingsViewState) {
+        // Maybe delete the pending avatar
+        (state.avatarAction as? RoomSettingsViewState.AvatarAction.UpdateAvatar)
+                ?.let { tryOrNull { it.newAvatarUri.toFile().delete() } }
+    }
+
     private fun cancel() {
-        deletePendingAvatar()
+        withState { deletePendingAvatar(it) }
 
         _viewEvents.post(RoomSettingsViewEvents.GoBack)
     }
@@ -180,7 +180,7 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
 
         when (val avatarAction = state.avatarAction) {
             RoomSettingsViewState.AvatarAction.None            -> Unit
-            RoomSettingsViewState.AvatarAction.DeleteAvatar -> {
+            RoomSettingsViewState.AvatarAction.DeleteAvatar    -> {
                 operationList.add(room.rx().deleteAvatar())
             }
             is RoomSettingsViewState.AvatarAction.UpdateAvatar -> {
@@ -209,8 +209,10 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
                 .subscribe(
                         {
                             postLoading(false)
-                            setState { copy(newHistoryVisibility = null) }
-                            deletePendingAvatar()
+                            setState {
+                                deletePendingAvatar(this)
+                                copy(newHistoryVisibility = null)
+                            }
                             _viewEvents.post(RoomSettingsViewEvents.Success)
                         },
                         {
diff --git a/vector/src/main/res/xml/vector_settings_security_privacy.xml b/vector/src/main/res/xml/vector_settings_security_privacy.xml
index fa26107edb..5dfde2d1df 100644
--- a/vector/src/main/res/xml/vector_settings_security_privacy.xml
+++ b/vector/src/main/res/xml/vector_settings_security_privacy.xml
@@ -115,7 +115,9 @@
 
     </im.vector.app.core.preference.VectorPreferenceCategory>
 
-    <im.vector.app.core.preference.VectorPreferenceCategory android:title="@string/settings_other">
+    <im.vector.app.core.preference.VectorPreferenceCategory
+        android:key="SETTINGS_SECURITY_OTHER_CATEGORY"
+        android:title="@string/settings_other">
 
         <im.vector.app.core.preference.VectorPreference
             android:key="SETTINGS_SECURITY_PIN"