diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInEvent.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInEvent.kt
index a8c0aba5198cd1c7f7bfa98a90e34dea8566ce5c..6d63a9ad96ffb646a7e7139721a1acf378597c2a 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInEvent.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInEvent.kt
@@ -1,8 +1,8 @@
 package de.rki.coronawarnapp.ui.eventregistration.attendee.checkins
 
-import androidx.annotation.StringRes
 import de.rki.coronawarnapp.eventregistration.checkins.CheckIn
 import de.rki.coronawarnapp.eventregistration.checkins.qrcode.VerifiedTraceLocation
+import de.rki.coronawarnapp.util.ui.LazyString
 
 sealed class CheckInEvent {
 
@@ -12,7 +12,7 @@ sealed class CheckInEvent {
 
     data class ConfirmCheckIn(val verifiedTraceLocation: VerifiedTraceLocation) : CheckInEvent()
 
-    data class InvalidQrCode(@StringRes val errorTextRes: Int) : CheckInEvent()
+    data class InvalidQrCode(val errorText: LazyString) : CheckInEvent()
 
     data class ConfirmCheckInWithoutHistory(val verifiedTraceLocation: VerifiedTraceLocation) : CheckInEvent()
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsFragment.kt
index d198e93cc2b4ac82228cc1215d73cec574e7fa7f..2b82e4dfe4d49c200a1aac9808c5e5d5a878af10 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsFragment.kt
@@ -7,7 +7,6 @@ import android.os.Bundle
 import android.provider.Settings
 import android.view.View
 import android.widget.Toast
-import androidx.annotation.StringRes
 import androidx.appcompat.app.AlertDialog
 import androidx.appcompat.widget.Toolbar
 import androidx.core.net.toUri
@@ -34,6 +33,7 @@ import de.rki.coronawarnapp.util.lists.decorations.TopBottomPaddingDecorator
 import de.rki.coronawarnapp.util.lists.diffutil.update
 import de.rki.coronawarnapp.util.onScroll
 import de.rki.coronawarnapp.util.tryHumanReadableError
+import de.rki.coronawarnapp.util.ui.LazyString
 import de.rki.coronawarnapp.util.ui.doNavigate
 import de.rki.coronawarnapp.util.ui.observe2
 import de.rki.coronawarnapp.util.ui.viewBindingLazy
@@ -99,7 +99,7 @@ class CheckInsFragment : Fragment(R.layout.trace_location_attendee_checkins_frag
                 )
             }
 
-            is CheckInEvent.InvalidQrCode -> showInvalidQrCodeInformation(event.errorTextRes)
+            is CheckInEvent.InvalidQrCode -> showInvalidQrCodeInformation(event.errorText)
 
             is CheckInEvent.ConfirmCheckInWithoutHistory -> doNavigate(
                 CheckInsFragmentDirections.actionCheckInsFragmentToConfirmCheckInFragmentCleanHistory(
@@ -135,12 +135,14 @@ class CheckInsFragment : Fragment(R.layout.trace_location_attendee_checkins_frag
         }
     }
 
-    private fun showInvalidQrCodeInformation(@StringRes errorTextRes: Int) =
+    private fun showInvalidQrCodeInformation(lazyErrorText: LazyString) {
         MaterialAlertDialogBuilder(requireContext()).apply {
-            setTitle(R.string.errors_generic_headline)
-            setMessage(errorTextRes)
-            setPositiveButton(R.string.errors_generic_button_positive) { _, _ -> }
+            val errorText = lazyErrorText.get(context)
+            setTitle(R.string.trace_location_attendee_invalid_qr_code_dialog_title)
+            setMessage(getString(R.string.trace_location_attendee_invalid_qr_code_dialog_message, errorText))
+            setPositiveButton(R.string.trace_location_attendee_invalid_qr_code_dialog_positive_button) { _, _ -> }
         }.show()
+    }
 
     private fun updateViews(items: List<CheckInsItem>) {
         checkInsAdapter.update(items)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModel.kt
index 94c98114e6d18bbff7bd7932ba116ef723bb7684..fcd6b21e036583455f604ff72bcea2fd70477cf0 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModel.kt
@@ -10,8 +10,6 @@ import de.rki.coronawarnapp.eventregistration.checkins.CheckIn
 import de.rki.coronawarnapp.eventregistration.checkins.CheckInRepository
 import de.rki.coronawarnapp.eventregistration.checkins.qrcode.QRCodeUriParser
 import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocationVerifier
-import de.rki.coronawarnapp.exception.ExceptionCategory
-import de.rki.coronawarnapp.exception.reporting.report
 import de.rki.coronawarnapp.presencetracing.checkins.checkout.CheckOutHandler
 import de.rki.coronawarnapp.ui.eventregistration.attendee.checkins.items.ActiveCheckInVH
 import de.rki.coronawarnapp.ui.eventregistration.attendee.checkins.items.CameraPermissionVH
@@ -22,6 +20,8 @@ import de.rki.coronawarnapp.util.coroutine.AppScope
 import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
 import de.rki.coronawarnapp.util.flow.intervalFlow
 import de.rki.coronawarnapp.util.ui.SingleLiveEvent
+import de.rki.coronawarnapp.util.ui.toLazyString
+import de.rki.coronawarnapp.util.ui.toResolvingString
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
 import kotlinx.coroutines.CoroutineScope
@@ -153,11 +153,12 @@ class CheckInsViewModel @AssistedInject constructor(
                         CheckInEvent.ConfirmCheckIn(verifyResult.verifiedTraceLocation)
                 )
                 is TraceLocationVerifier.VerificationResult.Invalid ->
-                    events.postValue(CheckInEvent.InvalidQrCode(verifyResult.errorTextRes))
+                    events.postValue(CheckInEvent.InvalidQrCode(verifyResult.errorTextRes.toResolvingString()))
             }
         } catch (e: Exception) {
             Timber.d(e, "TraceLocation verification failed")
-            e.report(ExceptionCategory.INTERNAL)
+            val msg = e.message ?: "QR-Code was invalid"
+            events.postValue(CheckInEvent.InvalidQrCode(msg.toLazyString()))
         }
     }
 
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 5c3fca69974e3af40f4dc192f67351442c4270bf..b47dc88f7005a23eccdca27d4a6077f733f0c089 100644
--- a/Corona-Warn-App/src/main/res/values-de/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-de/strings.xml
@@ -1992,4 +1992,13 @@
     <string name="trace_location_attendee_consent_dialog_positive_button">Teilen</string>
     <!-- XBUT: Trace location check-ins consent screen dialog negative button -->
     <string name="trace_location_attendee_consent_dialog_negative_button">Nicht teilen</string>
+
+    <!-- XHED: Trace location check-ins invalid qr code dialog title -->
+    <string name="trace_location_attendee_invalid_qr_code_dialog_title">QR-Code nicht gültig</string>
+    <!-- YTXT: Trace location check-ins invalid qr code dialog message -->
+    <string name="trace_location_attendee_invalid_qr_code_dialog_message">Der gescannte QR-Code ist nicht gültig.\nBitte scannen Sie einen gültigen QR-Code.\n\n(%1$s)</string>
+    <!-- XBUT: Trace location check-ins invalid qr code dialog positive button -->
+    <string name="trace_location_attendee_invalid_qr_code_dialog_positive_button">Ok</string>
+    <!-- XBUT: Trace location check-ins invalid qr code dialog negative button -->
+    <string name="trace_location_attendee_invalid_qr_code_dialog_negative_button">Abbrechen</string>
 </resources>
diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml
index 621fa7b8ed77dc036c2b89683eacc2b79dd091c1..94cde0a78666409f6a84c020244079069e885910 100644
--- a/Corona-Warn-App/src/main/res/values/strings.xml
+++ b/Corona-Warn-App/src/main/res/values/strings.xml
@@ -2000,4 +2000,13 @@
     <string name="trace_location_attendee_consent_dialog_positive_button">"Share"</string>
     <!-- XBUT: Trace location check-ins consent screen dialog negative button -->
     <string name="trace_location_attendee_consent_dialog_negative_button">"Don’t Share"</string>
+
+    <!-- XHED: Trace location check-ins invalid qr code dialog title -->
+    <string name="trace_location_attendee_invalid_qr_code_dialog_title">QR-Code nicht gültig</string>
+    <!-- YTXT: Trace location check-ins invalid qr code dialog message -->
+    <string name="trace_location_attendee_invalid_qr_code_dialog_message">Der gescannte QR-Code ist nicht gültig.\nBitte scannen Sie einen gültigen QR-Code.\n\n(%1$s)</string>
+    <!-- XBUT: Trace location check-ins invalid qr code dialog positive button -->
+    <string name="trace_location_attendee_invalid_qr_code_dialog_positive_button">Ok</string>
+    <!-- XBUT: Trace location check-ins invalid qr code dialog negative button -->
+    <string name="trace_location_attendee_invalid_qr_code_dialog_negative_button">Abbrechen</string>
 </resources>
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index c87a56f93c4012ed4cc76f15116472691e1c715c..441ea82353cabda2c43a082686e709f16d1ba509 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -19,5 +19,5 @@ org.gradle.dependency.verification.console=verbose
 # Versioning, this is used by the app & pipelines to calculate the current versionCode & versionName
 VERSION_MAJOR=2
 VERSION_MINOR=0
-VERSION_PATCH=3
+VERSION_PATCH=4
 VERSION_BUILD=0