diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/DebugLogger.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/DebugLogger.kt
index 00ccf795235bae3fc73efa24865fafd46731301e..57f7e38a498fc264bd3d577753690e6c9bc0ea09 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/DebugLogger.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/DebugLogger.kt
@@ -44,7 +44,7 @@ class DebugLogger(
 
     private var isDaggerReady = false
 
-    private val storageCheck = DebugLogStorageCheck(targetPath = debugDir, logWriter = logWriter)
+    val storageCheck = DebugLogStorageCheck(targetPath = debugDir, logWriter = logWriter)
     internal val isLogging = MutableStateFlow(false)
 
     val logState: Flow<LogState> = combine(
@@ -154,7 +154,7 @@ class DebugLogger(
                     yield()
                 }
 
-                if (storageCheck.checkLowStorage()) return@collect
+                if (storageCheck.isLowStorage()) return@collect
 
                 launch {
                     // Censor data sources need a moment to know what to censor
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/internal/DebugLogStorageCheck.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/internal/DebugLogStorageCheck.kt
index e61b0bf38c8ed5a749fca8a9f539f64f08d366e4..2e8e7aba28e5d7ff98e47bd3e462ad56739a48d4 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/internal/DebugLogStorageCheck.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/internal/DebugLogStorageCheck.kt
@@ -22,9 +22,9 @@ class DebugLogStorageCheck @Inject constructor(
         @SuppressLint("UsableSpace")
         get() = targetPath.usableSpace
 
-    fun checkLowStorage(): Boolean {
+    fun isLowStorage(forceCheck: Boolean = false): Boolean {
         val now = timeProvider()
-        if (now - lastCheckAt < 5_000) return isLowStorage.value
+        if (!forceCheck && now - lastCheckAt < 5_000) return isLowStorage.value
 
         val currentSpace = try {
             availableSpace
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/ui/DebugLogFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/ui/DebugLogFragment.kt
index 867383a624a76ae8356d2e97322d8f7d599dadfe..41f63891d30d37f5c88b944ffb680da7b35a4bef 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/ui/DebugLogFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/ui/DebugLogFragment.kt
@@ -3,16 +3,19 @@ package de.rki.coronawarnapp.bugreporting.debuglog.ui
 import android.app.Activity
 import android.content.Intent
 import android.os.Bundle
+import android.provider.Settings
 import android.text.format.Formatter
 import android.view.View
 import android.widget.Toast
 import androidx.core.view.isGone
 import androidx.fragment.app.Fragment
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.BugreportingDebuglogFragmentBinding
 import de.rki.coronawarnapp.util.ContextExtensions.getDrawableCompat
 import de.rki.coronawarnapp.util.di.AutoInject
 import de.rki.coronawarnapp.util.setUrl
+import de.rki.coronawarnapp.util.tryHumanReadableError
 import de.rki.coronawarnapp.util.ui.doNavigate
 import de.rki.coronawarnapp.util.ui.observe2
 import de.rki.coronawarnapp.util.ui.popBackStack
@@ -29,9 +32,11 @@ class DebugLogFragment : Fragment(R.layout.bugreporting_debuglog_fragment), Auto
     private val vm: DebugLogViewModel by cwaViewModels { viewModelFactory }
     private val binding: BugreportingDebuglogFragmentBinding by viewBindingLazy()
 
+    @Suppress("ComplexMethod")
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
 
+        // Static screen elements
         binding.apply {
             toolbar.setNavigationOnClickListener { popBackStack() }
 
@@ -94,41 +99,48 @@ class DebugLogFragment : Fragment(R.layout.bugreporting_debuglog_fragment), Auto
             }
         }
 
-        vm.shareEvent.observe2(this@DebugLogFragment) {
-            startActivityForResult(it.createIntent(), it.id)
-        }
-
-        vm.logStoreResult.observe2(this) {
-            Toast.makeText(
-                requireContext(),
-                "TODO: Show store result dialog: ${it.storageUri}",
-                Toast.LENGTH_LONG
-            ).show()
+        vm.events.observe2(this) {
+            when (it) {
+                DebugLogViewModel.Event.ShowLogDeletedConfirmation -> {
+                    showLogDeletionConfirmation()
+                }
+                DebugLogViewModel.Event.NavigateToPrivacyFragment -> {
+                    doNavigate(
+                        DebugLogFragmentDirections.actionDebuglogFragmentToInformationPrivacyFragment()
+                    )
+                }
+                DebugLogViewModel.Event.NavigateToUploadFragment -> {
+                    doNavigate(
+                        DebugLogFragmentDirections.actionDebuglogFragmentToDebugLogUploadFragment()
+                    )
+                }
+                DebugLogViewModel.Event.NavigateToUploadHistory -> {
+                    doNavigate(
+                        DebugLogFragmentDirections.actionDebuglogFragmentToLogUploadHistoryFragment()
+                    )
+                }
+                is DebugLogViewModel.Event.Error -> {
+                    Toast.makeText(requireContext(), it.toString(), Toast.LENGTH_LONG).show()
+                }
+                DebugLogViewModel.Event.ShowLowStorageDialog -> {
+                    showLowStorageError()
+                }
+                is DebugLogViewModel.Event.LocalExport -> {
+                    startActivityForResult(it.request.createIntent(), it.request.id)
+                }
+                is DebugLogViewModel.Event.ExportResult -> {
+                    showExportResult()
+                }
+                is DebugLogViewModel.Event.ShowLocalExportError -> {
+                    showLocalExportError(it.error)
+                }
+            }
         }
 
         vm.logUploads.observe2(this@DebugLogFragment) {
             binding.debugLogHistoryContainer.setGone(it.logs.isEmpty())
         }
         binding.debugLogHistoryContainer.setOnClickListener { vm.onIdHistoryPress() }
-
-        vm.routeToScreen.observe2(this) {
-            when (it) {
-                DebugLogNavigationEvents.NavigateToPrivacyFragment -> doNavigate(
-                    DebugLogFragmentDirections.actionDebuglogFragmentToInformationPrivacyFragment()
-                )
-                DebugLogNavigationEvents.NavigateToUploadHistory -> doNavigate(
-                    DebugLogFragmentDirections.actionDebuglogFragmentToLogUploadHistoryFragment()
-                )
-
-                DebugLogNavigationEvents.NavigateToShareFragment -> doNavigate(
-                    DebugLogFragmentDirections.actionDebuglogFragmentToDebugLogUploadFragment()
-                )
-            }
-        }
-
-        vm.errorEvent.observe2(this) {
-            Toast.makeText(requireContext(), it.toString(), Toast.LENGTH_LONG).show()
-        }
     }
 
     override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
@@ -138,4 +150,52 @@ class DebugLogFragment : Fragment(R.layout.bugreporting_debuglog_fragment), Auto
             if (resultCode == Activity.RESULT_OK) resultData?.data else null
         )
     }
+
+    private fun showLogDeletionConfirmation() {
+        MaterialAlertDialogBuilder(requireContext()).apply {
+            setMessage(R.string.debugging_debuglog_stop_confirmation_message)
+            setPositiveButton(android.R.string.yes) { _, _ -> }
+        }.show()
+    }
+
+    private fun showLowStorageError() {
+        MaterialAlertDialogBuilder(requireContext()).apply {
+            setTitle(R.string.errors_generic_headline_short)
+            setMessage(R.string.debugging_debuglog_start_low_storage_error)
+            setPositiveButton(android.R.string.yes) { _, _ -> /* dismiss */ }
+            setNeutralButton(R.string.menu_settings) { _, _ ->
+                try {
+                    startActivity(Intent(Settings.ACTION_INTERNAL_STORAGE_SETTINGS))
+                } catch (e: Exception) {
+                    Toast.makeText(requireContext(), e.toString(), Toast.LENGTH_LONG).show()
+                }
+            }
+        }.show()
+    }
+
+    private fun showExportResult() {
+        MaterialAlertDialogBuilder(requireContext()).apply {
+            setTitle(R.string.debugging_debuglog_localexport_title)
+            setMessage(R.string.debugging_debuglog_localexport_message)
+            setPositiveButton(android.R.string.yes) { _, _ -> /* dismiss */ }
+        }.show()
+    }
+
+    private fun showLocalExportError(cause: Throwable) {
+        MaterialAlertDialogBuilder(requireContext()).apply {
+            setTitle(R.string.errors_generic_headline_short)
+            setMessage(
+                getString(R.string.debugging_debuglog_localexport_error_message) + "\n(" +
+                    cause.tryHumanReadableError(requireContext()).description + ")"
+            )
+            setPositiveButton(android.R.string.yes) { _, _ -> /* dismiss */ }
+            setNeutralButton(R.string.menu_settings) { _, _ ->
+                try {
+                    startActivity(Intent(Settings.ACTION_INTERNAL_STORAGE_SETTINGS))
+                } catch (e: Exception) {
+                    Toast.makeText(requireContext(), e.toString(), Toast.LENGTH_LONG).show()
+                }
+            }
+        }.show()
+    }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/ui/DebugLogViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/ui/DebugLogViewModel.kt
index cad3fa356498e026688e470506e56296c256ed6a..ec5b7e32885e1c8442c4ea6db27388008d247144 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/ui/DebugLogViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/ui/DebugLogViewModel.kt
@@ -20,6 +20,7 @@ import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.combine
 import timber.log.Timber
+import java.io.IOException
 
 class DebugLogViewModel @AssistedInject constructor(
     private val debugLogger: DebugLogger,
@@ -33,8 +34,6 @@ class DebugLogViewModel @AssistedInject constructor(
 
     private val isActionInProgress = MutableStateFlow(false)
 
-    val routeToScreen = SingleLiveEvent<DebugLogNavigationEvents>()
-
     val logUploads = bugReportingSettings.uploadHistory.flow
         .asLiveData(context = dispatcherProvider.Default)
 
@@ -50,26 +49,31 @@ class DebugLogViewModel @AssistedInject constructor(
         )
     }.asLiveData(context = dispatcherProvider.Default)
 
-    val errorEvent = SingleLiveEvent<Throwable>()
-    val shareEvent = SingleLiveEvent<SAFLogExport.Request>()
-    val logStoreResult = SingleLiveEvent<SAFLogExport.Request.Result>()
+    val events = SingleLiveEvent<Event>()
 
     fun onPrivacyButtonPress() {
-        routeToScreen.postValue(DebugLogNavigationEvents.NavigateToPrivacyFragment)
+        events.postValue(Event.NavigateToPrivacyFragment)
     }
 
     fun onShareButtonPress() {
-        routeToScreen.postValue(DebugLogNavigationEvents.NavigateToShareFragment)
+        events.postValue(Event.NavigateToUploadFragment)
     }
 
     fun onIdHistoryPress() {
-        routeToScreen.postValue(DebugLogNavigationEvents.NavigateToUploadHistory)
+        events.postValue(Event.NavigateToUploadHistory)
     }
 
     fun onToggleRecording() = launchWithProgress {
         if (debugLogger.isLogging.value) {
             debugLogger.stop()
+            events.postValue(Event.ShowLogDeletedConfirmation)
         } else {
+            if (debugLogger.storageCheck.isLowStorage(forceCheck = true)) {
+                Timber.d("Low storage, not starting logger.")
+                events.postValue(Event.ShowLowStorageDialog)
+                return@launchWithProgress
+            }
+
             debugLogger.start()
 
             CWADebug.logDeviceInfos()
@@ -86,7 +90,7 @@ class DebugLogViewModel @AssistedInject constructor(
         Timber.d("storeLog()")
         val snapshot = logSnapshotter.snapshot()
         val shareRequest = safLogExport.createSAFRequest(snapshot)
-        shareEvent.postValue(shareRequest)
+        events.postValue(Event.LocalExport(shareRequest))
     }
 
     fun processSAFResult(requestCode: Int, safPath: Uri?) = launchWithProgress {
@@ -101,10 +105,14 @@ class DebugLogViewModel @AssistedInject constructor(
             return@launchWithProgress
         }
 
-        val storageResult = request.storeSnapshot(contentResolver, safPath)
-        Timber.i("Log stored %s", storageResult)
-
-        logStoreResult.postValue(storageResult)
+        try {
+            val storageResult = request.storeSnapshot(contentResolver, safPath)
+            Timber.i("Log stored %s", storageResult)
+            events.postValue(Event.ExportResult(storageResult))
+        } catch (e: IOException) {
+            Timber.e(e, "Failed to store log file.")
+            events.postValue(Event.ShowLocalExportError(e))
+        }
     }
 
     private fun launchWithProgress(
@@ -119,7 +127,7 @@ class DebugLogViewModel @AssistedInject constructor(
                 block()
             } catch (e: Throwable) {
                 Timber.e(e, "launchWithProgress() failed.")
-                errorEvent.postValue(e)
+                events.postValue(Event.Error(e))
             } finally {
                 val duration = System.currentTimeMillis() - startTime
                 Timber.v("launchWithProgress() took ${duration}ms")
@@ -135,6 +143,18 @@ class DebugLogViewModel @AssistedInject constructor(
         val currentSize: Long = 0
     )
 
+    sealed class Event {
+        object NavigateToPrivacyFragment : Event()
+        object NavigateToUploadFragment : Event()
+        object NavigateToUploadHistory : Event()
+        object ShowLogDeletedConfirmation : Event()
+        object ShowLowStorageDialog : Event()
+        data class ShowLocalExportError(val error: Throwable) : Event()
+        data class Error(val error: Throwable) : Event()
+        data class LocalExport(val request: SAFLogExport.Request) : Event()
+        data class ExportResult(val result: SAFLogExport.Request.Result) : Event()
+    }
+
     @AssistedFactory
     interface Factory : SimpleCWAViewModelFactory<DebugLogViewModel>
 }
diff --git a/Corona-Warn-App/src/main/res/values-de/strings.xml b/Corona-Warn-App/src/main/res/values-de/strings.xml
index ff29781c4f705364b86ac526fe26b4c939a38586..ce0bebb41c5db8158339ab7dd75f467ff4ae8fc7 100644
--- a/Corona-Warn-App/src/main/res/values-de/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-de/strings.xml
@@ -899,8 +899,16 @@
     <string name="debugging_debuglog_status_not_recording">"Inaktiv"</string>
     <!-- YTXT: Describtion for current logging status text if a debug log is not being recorded -->
     <string name="debugging_debuglog_status_additional_infos">"Derzeitige Größe: %1$s (unkomprimiert)"</string>
-    <!-- XHED: Title for native sharing dialog -->
-    <string name="debugging_debuglog_sharing_dialog_title">"CWA Fehlerbericht teilen"</string>
+    <!-- YTXT: Dialog message if the log recording is stopped, and thus deleted. -->
+    <string name="debugging_debuglog_stop_confirmation_message">"Der Fehlerbericht wurde gelöscht. Wenn Sie eine lokale Kopie des Fehlerberichts gespeichert haben, wurde diese nicht gelöscht."</string>
+    <!-- YTXT: Dialog message if there is not enough free storage to start a debug log -->
+    <string name="debugging_debuglog_start_low_storage_error">"Sie brauchen mindestens 200 MB  Speicherplatz, um die Fehleranalyse zu starten. Bitte geben Sie Speicherplatz frei."</string>
+    <!-- XHED: Dialog title if a user has stored a debug log locally -->
+    <string name="debugging_debuglog_localexport_title">"Lokal gespeichert"</string>
+    <!-- YTXT: Dialog message if a user has stored a debug log locally -->
+    <string name="debugging_debuglog_localexport_message">"Die Fehleranalyse wurde lokal gespeichert."</string>
+    <!-- YTXT: Dialog message if local export has failed -->
+    <string name="debugging_debuglog_localexport_error_message">"Das Speichern des Fehlerberichts ist fehlgeschlagen. Bitte überprüfen Sie, ob genügend Speicherplatz zur Verfügung steht."</string>
 
     <!-- XHED: Title for debug legal screen -->
     <string name="debugging_debuglog_legal_dialog_title">"Ausführliche Informationen zur Übersendung der Fehlerberichte"</string>
@@ -1620,6 +1628,8 @@
                Generic Error Messages
         ###################################### -->
     <!-- XHED: error dialog - headline -->
+    <string name="errors_generic_headline_short">"Fehler"</string>
+    <!-- XHED: error dialog - headline -->
     <string name="errors_generic_headline">"Etwas ist schiefgelaufen."</string>
     <!-- XTXT: error dialog - short text for error reason -->
     <string name="errors_generic_details_headline">"Ursache"</string>
diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml
index 60b7b297a475ed3cd145c2a0ab60b35a11504227..315ee7ea00279280d352ddce2e884c6bd7c27135 100644
--- a/Corona-Warn-App/src/main/res/values/strings.xml
+++ b/Corona-Warn-App/src/main/res/values/strings.xml
@@ -918,6 +918,16 @@
     <string name="debugging_debuglog_status_additional_infos">"Current size: %1$s (uncompressed)"</string>
     <!-- XHED: Title for native sharing dialog -->
     <string name="debugging_debuglog_sharing_dialog_title">"Share CWA Error Report"</string>
+    <!-- YTXT: Dialog message if the log recording is stopped, and thus deleted. -->
+    <string name="debugging_debuglog_stop_confirmation_message">"Der Fehlerbericht wurde gelöscht. Wenn Sie eine lokale Kopie des Fehlerberichts gespeichert haben, wurde diese nicht gelöscht."</string>
+    <!-- YTXT: Dialog message if there is not enough free storage to start a debug log -->
+    <string name="debugging_debuglog_start_low_storage_error">Sie brauchen mindestens 200 MB  Speicherplatz, um die Fehleranalyse zu starten. Bitte geben Sie Speicherplatz frei.</string>
+    <!-- XHED: Dialog title if a user has stored a debug log locally -->
+    <string name="debugging_debuglog_localexport_title">"Lokal gespeichert"</string>
+    <!-- YTXT: Dialog message if a user has stored a debug log locally -->
+    <string name="debugging_debuglog_localexport_message">"Die Fehleranalyse wurde lokal gespeichert."</string>
+    <!-- YTXT: Dialog message if local export has failed -->
+    <string name="debugging_debuglog_localexport_error_message">"Das Speichern des Fehlerberichts ist fehlgeschlagen. Bitte überprüfen Sie, ob genügend Speicherplatz zur Verfügung steht."</string>
 
     <!-- XHED: Title for debug legal screen -->
     <string name="debugging_debuglog_legal_dialog_title">"Ausführliche Informationen zur Übersendung der Fehlerberichte"</string>
@@ -1638,6 +1648,8 @@
                Generic Error Messages
         ###################################### -->
     <!-- XHED: error dialog - headline -->
+    <string name="errors_generic_headline_short">"Error"</string>
+    <!-- XHED: error dialog - headline -->
     <string name="errors_generic_headline">"Something went wrong."</string>
     <!-- XTXT: error dialog - short text for error reason -->
     <string name="errors_generic_details_headline">"Cause"</string>
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/internal/DebugLogStorageCheckTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/internal/DebugLogStorageCheckTest.kt
index 0b3e7884a89177d57fe9771c6ba46a1e417e4e69..44a2d6e19db22d8fc66b3051676818880435a606 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/internal/DebugLogStorageCheckTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/internal/DebugLogStorageCheckTest.kt
@@ -44,7 +44,7 @@ class DebugLogStorageCheckTest : BaseTest() {
     @Test
     fun `normal not low storage case`() {
         val instance = createInstance()
-        instance.checkLowStorage() shouldBe false
+        instance.isLowStorage() shouldBe false
 
         verify { logWriter wasNot Called }
     }
@@ -58,7 +58,7 @@ class DebugLogStorageCheckTest : BaseTest() {
         every { logWriter.write(capture(logSlot)) } just Runs
 
         val instance = createInstance()
-        instance.checkLowStorage() shouldBe true
+        instance.isLowStorage() shouldBe true
 
         logSlot.captured.throwable shouldBe unexpectedError
     }
@@ -67,11 +67,11 @@ class DebugLogStorageCheckTest : BaseTest() {
     fun `low storage default is 200MB`() {
         every { targetPath.usableSpace } returns 199 * 1000 * 1024L
         val instance = createInstance()
-        instance.checkLowStorage() shouldBe true
-        instance.checkLowStorage() shouldBe true
+        instance.isLowStorage() shouldBe true
+        instance.isLowStorage() shouldBe true
 
         currentTime += 60 * 1000L
-        instance.checkLowStorage() shouldBe true
+        instance.isLowStorage() shouldBe true
 
         // We only write the warning once
         verify(exactly = 1) { logWriter.write(any()) }
@@ -80,21 +80,21 @@ class DebugLogStorageCheckTest : BaseTest() {
     @Test
     fun `checks happen at most every 5 seconds`() {
         val instance = createInstance()
-        instance.checkLowStorage() shouldBe false
+        instance.isLowStorage() shouldBe false
 
         every { targetPath.usableSpace } returns 1024L
 
-        instance.checkLowStorage() shouldBe false
+        instance.isLowStorage() shouldBe false
 
         verify(exactly = 1) { targetPath.usableSpace }
 
         currentTime += 5000L
 
-        instance.checkLowStorage() shouldBe true
+        instance.isLowStorage() shouldBe true
 
         every { targetPath.usableSpace } returns 250 * 1000 * 1024L
 
-        instance.checkLowStorage() shouldBe true
+        instance.isLowStorage() shouldBe true
 
         verify(exactly = 2) { targetPath.usableSpace }
     }