diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/CoronaTestQRCodeValidator.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/CoronaTestQRCodeValidator.kt
index 7b31a977326e8cf8f72a7b76938766d79e1c1d3f..4f12913e4e45402456e2a37edb17a920429ae085 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/CoronaTestQRCodeValidator.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/CoronaTestQRCodeValidator.kt
@@ -13,7 +13,7 @@ class CoronaTestQrCodeValidator @Inject constructor(
 
     fun validate(rawString: String): CoronaTestQRCode {
         return findExtractor(rawString)
-            ?.extract(rawString)
+            ?.extract(rawString, mode = QrCodeExtractor.Mode.TEST_STRICT)
             ?.also { Timber.i("Extracted data from QR code is %s", it) }
             ?: throw InvalidQRCodeException()
     }
@@ -25,5 +25,11 @@ class CoronaTestQrCodeValidator @Inject constructor(
 
 interface QrCodeExtractor<T> {
     fun canHandle(rawString: String): Boolean
-    fun extract(rawString: String): T
+    fun extract(rawString: String, mode: Mode): T
+
+    enum class Mode {
+        TEST_STRICT,
+        CERT_VAC_STRICT,
+        CERT_VAC_LENIENT
+    }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/PcrQrCodeExtractor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/PcrQrCodeExtractor.kt
index 49633e3decd06846753a897897b235a16409cbdd..c94eb873ff48e73c1fca6cd54a7b7994fe46373f 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/PcrQrCodeExtractor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/PcrQrCodeExtractor.kt
@@ -8,7 +8,7 @@ class PcrQrCodeExtractor @Inject constructor() : QrCodeExtractor<CoronaTestQRCod
 
     override fun canHandle(rawString: String): Boolean = rawString.startsWith(prefix, ignoreCase = true)
 
-    override fun extract(rawString: String): CoronaTestQRCode.PCR {
+    override fun extract(rawString: String, mode: QrCodeExtractor.Mode): CoronaTestQRCode.PCR {
         val guid = extractGUID(rawString)
         PcrQrCodeCensor.lastGUID = guid
         return CoronaTestQRCode.PCR(guid)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/RapidAntigenQrCodeExtractor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/RapidAntigenQrCodeExtractor.kt
index c5881f97364a97bd6c5f8c795b3b1df7c1c72df0..96dd01a7122a7c1a7c43f1497a96e774aff4ef2b 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/RapidAntigenQrCodeExtractor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/RapidAntigenQrCodeExtractor.kt
@@ -19,7 +19,7 @@ class RapidAntigenQrCodeExtractor @Inject constructor() : QrCodeExtractor<Corona
         return rawString.startsWith(PREFIX1, ignoreCase = true) || rawString.startsWith(PREFIX2, ignoreCase = true)
     }
 
-    override fun extract(rawString: String): CoronaTestQRCode.RapidAntigen {
+    override fun extract(rawString: String, mode: QrCodeExtractor.Mode): CoronaTestQRCode.RapidAntigen {
         Timber.v("extract(rawString=%s)", rawString)
         val payload = CleanPayload(extractData(rawString))
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/certificate/InvalidHealthCertificateException.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/certificate/InvalidHealthCertificateException.kt
index 39061747c4f618f90d15b5d58f4b3a6bf1d3f785..14110a6f27dea9b9fabf4becdca12ade72163147 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/certificate/InvalidHealthCertificateException.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/certificate/InvalidHealthCertificateException.kt
@@ -19,6 +19,7 @@ import de.rki.coronawarnapp.vaccination.core.certificate.InvalidHealthCertificat
 import de.rki.coronawarnapp.vaccination.core.certificate.InvalidHealthCertificateException.ErrorCode.VC_HC_CWT_NO_HCERT
 import de.rki.coronawarnapp.vaccination.core.certificate.InvalidHealthCertificateException.ErrorCode.VC_HC_CWT_NO_ISS
 import de.rki.coronawarnapp.vaccination.core.certificate.InvalidHealthCertificateException.ErrorCode.VC_JSON_SCHEMA_INVALID
+import de.rki.coronawarnapp.vaccination.core.certificate.InvalidHealthCertificateException.ErrorCode.VC_MULTIPLE_VACCINATION_ENTRIES
 import de.rki.coronawarnapp.vaccination.core.certificate.InvalidHealthCertificateException.ErrorCode.VC_NAME_MISMATCH
 import de.rki.coronawarnapp.vaccination.core.certificate.InvalidHealthCertificateException.ErrorCode.VC_NO_VACCINATION_ENTRY
 import de.rki.coronawarnapp.vaccination.core.certificate.InvalidHealthCertificateException.ErrorCode.VC_PREFIX_INVALID
@@ -36,6 +37,7 @@ class InvalidHealthCertificateException(
         HC_COSE_MESSAGE_INVALID("COSE message invalid."),
         HC_CBOR_DECODING_FAILED("CBOR decoding failed."),
         VC_NO_VACCINATION_ENTRY("Vaccination certificate missing."),
+        VC_MULTIPLE_VACCINATION_ENTRIES("Multiple vaccination certificates."),
         VC_PREFIX_INVALID("Prefix invalid."),
         VC_STORING_FAILED("Storing failed."),
         VC_JSON_SCHEMA_INVALID("Json schema invalid."),
@@ -73,6 +75,9 @@ class InvalidHealthCertificateException(
             VC_NO_VACCINATION_ENTRY -> CachedString { context ->
                 context.getString(ERROR_MESSAGE_VC_NOT_YET_SUPPORTED)
             }
+            VC_MULTIPLE_VACCINATION_ENTRIES -> CachedString { context ->
+                context.getString(ERROR_MESSAGE_VC_NOT_YET_SUPPORTED)
+            }
             VC_STORING_FAILED -> CachedString { context ->
                 context.getString(ERROR_MESSAGE_VC_SCAN_AGAIN)
             }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/certificate/VaccinationDGCV1Parser.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/certificate/VaccinationDGCV1Parser.kt
index e25defbc9cab81c1be8c37c0f6aba41716b14f75..be296d648c23287016daedb4ba60b168e5e36756 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/certificate/VaccinationDGCV1Parser.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/certificate/VaccinationDGCV1Parser.kt
@@ -9,7 +9,9 @@ import de.rki.coronawarnapp.vaccination.core.certificate.InvalidHealthCertificat
 import de.rki.coronawarnapp.vaccination.core.certificate.InvalidHealthCertificateException.ErrorCode.VC_HC_CWT_NO_DGC
 import de.rki.coronawarnapp.vaccination.core.certificate.InvalidHealthCertificateException.ErrorCode.VC_HC_CWT_NO_HCERT
 import de.rki.coronawarnapp.vaccination.core.certificate.InvalidHealthCertificateException.ErrorCode.VC_JSON_SCHEMA_INVALID
+import de.rki.coronawarnapp.vaccination.core.certificate.InvalidHealthCertificateException.ErrorCode.VC_MULTIPLE_VACCINATION_ENTRIES
 import de.rki.coronawarnapp.vaccination.core.certificate.InvalidHealthCertificateException.ErrorCode.VC_NO_VACCINATION_ENTRY
+import timber.log.Timber
 import javax.inject.Inject
 
 @Reusable
@@ -17,35 +19,44 @@ class VaccinationDGCV1Parser @Inject constructor(
     @BaseGson private val gson: Gson
 ) {
 
-    fun parse(map: CBORObject): VaccinationDGCV1 = try {
+    fun parse(map: CBORObject, lenient: Boolean): VaccinationDGCV1 = try {
         val certificate: VaccinationDGCV1 = map[keyHCert]?.run {
             this[keyEuDgcV1]?.run {
                 toCertificate()
             } ?: throw InvalidHealthCertificateException(VC_HC_CWT_NO_DGC)
         } ?: throw InvalidHealthCertificateException(VC_HC_CWT_NO_HCERT)
 
-        certificate.validate()
+        certificate.toValidated(lenient)
     } catch (e: InvalidHealthCertificateException) {
         throw e
     } catch (e: Throwable) {
         throw InvalidHealthCertificateException(HC_CBOR_DECODING_FAILED)
     }
 
-    private fun VaccinationDGCV1.validate(): VaccinationDGCV1 {
-        if (vaccinationDatas.isEmpty()) {
-            throw InvalidHealthCertificateException(VC_NO_VACCINATION_ENTRY)
+    private fun VaccinationDGCV1.toValidated(lenient: Boolean): VaccinationDGCV1 = this
+        .run {
+            if (vaccinationDatas.isEmpty()) throw InvalidHealthCertificateException(VC_NO_VACCINATION_ENTRY)
+
+            if (vaccinationDatas.size == 1) return@run this
+
+            if (lenient) {
+                Timber.w("Lenient: Vaccination data contained multiple entries.")
+                copy(vaccinationDatas = listOf(vaccinationDatas.maxByOrNull { it.vaccinatedAt }!!))
+            } else {
+                throw InvalidHealthCertificateException(VC_MULTIPLE_VACCINATION_ENTRIES)
+            }
         }
-        // Force date parsing
-        dateOfBirth
-        vaccinationDatas.forEach {
-            it.vaccinatedAt
+        .also {
+            // Force date parsing
+            dateOfBirth
+            vaccinationDatas.forEach {
+                it.vaccinatedAt
+            }
         }
-        return this
-    }
 
-    private fun CBORObject.toCertificate() = try {
+    private fun CBORObject.toCertificate(): VaccinationDGCV1 = try {
         val json = ToJSONString()
-        gson.fromJson<VaccinationDGCV1>(json)
+        gson.fromJson(json)
     } catch (e: Throwable) {
         throw InvalidHealthCertificateException(VC_JSON_SCHEMA_INVALID)
     }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/qrcode/VaccinationQRCodeExtractor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/qrcode/VaccinationQRCodeExtractor.kt
index ae3065df399be47ee02e1d6fe5650ad3ea51b2a0..d1d9496bf223ce36540593ec572234cf84343a56 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/qrcode/VaccinationQRCodeExtractor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/qrcode/VaccinationQRCodeExtractor.kt
@@ -22,14 +22,14 @@ class VaccinationQRCodeExtractor @Inject constructor(
 
     override fun canHandle(rawString: String): Boolean = rawString.startsWith(PREFIX)
 
-    override fun extract(rawString: String): VaccinationCertificateQRCode {
+    override fun extract(rawString: String, mode: QrCodeExtractor.Mode): VaccinationCertificateQRCode {
         CertificateQrCodeCensor.addQRCodeStringToCensor(rawString)
 
         val parsedData = rawString
             .removePrefix(PREFIX)
             .decodeBase45()
             .decompress()
-            .parse()
+            .parse(lenient = mode == QrCodeExtractor.Mode.CERT_VAC_LENIENT)
 
         return VaccinationCertificateQRCode(
             parsedData = parsedData,
@@ -51,13 +51,13 @@ class VaccinationQRCodeExtractor @Inject constructor(
         throw InvalidHealthCertificateException(HC_ZLIB_DECOMPRESSION_FAILED)
     }
 
-    fun RawCOSEObject.parse(): VaccinationCertificateData {
+    fun RawCOSEObject.parse(lenient: Boolean): VaccinationCertificateData {
         Timber.v("Parsing COSE for vaccination certificate.")
         val cbor = coseDecoder.decode(this)
 
         return VaccinationCertificateData(
             header = headerParser.parse(cbor),
-            certificate = bodyParser.parse(cbor)
+            certificate = bodyParser.parse(cbor, lenient = lenient)
         ).also {
             CertificateQrCodeCensor.addCertificateToCensor(it)
         }.also {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/qrcode/VaccinationQRCodeValidator.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/qrcode/VaccinationQRCodeValidator.kt
index 3e7f603962d7306ea8bde1da607008559c94c7c1..aefdff6e55018d336945ec001a55372081040f66 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/qrcode/VaccinationQRCodeValidator.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/qrcode/VaccinationQRCodeValidator.kt
@@ -17,7 +17,7 @@ class VaccinationQRCodeValidator @Inject constructor(
         // If there is more than one "extractor" in the future, check censoring again.
         // CertificateQrCodeCensor.addQRCodeStringToCensor(rawString)
         return findExtractor(rawString)
-            ?.extract(rawString)
+            ?.extract(rawString, mode = QrCodeExtractor.Mode.CERT_VAC_STRICT)
             ?.also { Timber.i("Extracted data from QR code is %s", it) }
             ?: throw InvalidHealthCertificateException(VC_PREFIX_INVALID)
     }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/repository/storage/VaccinationContainer.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/repository/storage/VaccinationContainer.kt
index 9694f5f9d6875b21d3075f90a8dfd52068574962..7914dd2788155a949e4c73860b1aaaaa82d7d685 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/repository/storage/VaccinationContainer.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/repository/storage/VaccinationContainer.kt
@@ -2,6 +2,7 @@ package de.rki.coronawarnapp.vaccination.core.repository.storage
 
 import androidx.annotation.Keep
 import com.google.gson.annotations.SerializedName
+import de.rki.coronawarnapp.coronatest.qrcode.QrCodeExtractor.Mode
 import de.rki.coronawarnapp.vaccination.core.VaccinatedPersonIdentifier
 import de.rki.coronawarnapp.vaccination.core.VaccinationCertificate
 import de.rki.coronawarnapp.vaccination.core.certificate.CoseCertificateHeader
@@ -33,7 +34,7 @@ data class VaccinationContainer internal constructor(
 
     @delegate:Transient
     internal val certificateData: VaccinationCertificateData by lazy {
-        preParsedData ?: qrCodeExtractor.extract(vaccinationQrCode).parsedData
+        preParsedData ?: qrCodeExtractor.extract(vaccinationQrCode, mode = Mode.CERT_VAC_LENIENT).parsedData
     }
 
     val header: CoseCertificateHeader
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/qrcode/CoronaTestQrCodeValidatorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/qrcode/CoronaTestQrCodeValidatorTest.kt
index f9665d0af78f7a9f90b8e8157cd5d915f0e689af..e5cdb3f4c89a6d10f13910bbc6610c7cbb7ebf9f 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/qrcode/CoronaTestQrCodeValidatorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/qrcode/CoronaTestQrCodeValidatorTest.kt
@@ -1,16 +1,21 @@
 package de.rki.coronawarnapp.coronatest.qrcode
 
+import de.rki.coronawarnapp.coronatest.qrcode.QrCodeExtractor.Mode
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
 import io.kotest.assertions.throwables.shouldThrow
 import io.kotest.matchers.shouldBe
+import io.mockk.spyk
+import io.mockk.verify
 import org.junit.jupiter.api.Test
 import testhelpers.BaseTest
 
 class CoronaTestQrCodeValidatorTest : BaseTest() {
+    private val raExtractor = spyk(RapidAntigenQrCodeExtractor())
+    private val pcrExtractor = spyk(PcrQrCodeExtractor())
 
     @Test
     fun `valid codes are extracted by corresponding extractor`() {
-        val instance = CoronaTestQrCodeValidator(RapidAntigenQrCodeExtractor(), PcrQrCodeExtractor())
+        val instance = CoronaTestQrCodeValidator(raExtractor, pcrExtractor)
         instance.validate(pcrQrCode1).type shouldBe CoronaTest.Type.PCR
         instance.validate(pcrQrCode2).type shouldBe CoronaTest.Type.PCR
         instance.validate(pcrQrCode3).type shouldBe CoronaTest.Type.PCR
@@ -22,7 +27,7 @@ class CoronaTestQrCodeValidatorTest : BaseTest() {
     @Test
     fun `invalid prefix throws exception`() {
         val invalidCode = "HTTPS://somethingelse/?123456-12345678-1234-4DA7-B166-B86D85475064"
-        val instance = CoronaTestQrCodeValidator(RapidAntigenQrCodeExtractor(), PcrQrCodeExtractor())
+        val instance = CoronaTestQrCodeValidator(raExtractor, pcrExtractor)
         shouldThrow<InvalidQRCodeException> {
             instance.validate(invalidCode)
         }
@@ -31,9 +36,18 @@ class CoronaTestQrCodeValidatorTest : BaseTest() {
     @Test
     fun `invalid json throws exception`() {
         val invalidCode = "https://s.coronawarn.app/?v=1#eyJ0aW1lc3RhbXAiOjE2"
-        val instance = CoronaTestQrCodeValidator(RapidAntigenQrCodeExtractor(), PcrQrCodeExtractor())
+        val instance = CoronaTestQrCodeValidator(raExtractor, pcrExtractor)
         shouldThrow<InvalidQRCodeException> {
             instance.validate(invalidCode)
         }
     }
+
+    @Test
+    fun `validator uses strict extraction mode`() {
+        val instance = CoronaTestQrCodeValidator(raExtractor, pcrExtractor)
+        instance.validate(pcrQrCode1).type shouldBe CoronaTest.Type.PCR
+        verify { pcrExtractor.extract(pcrQrCode1, Mode.TEST_STRICT) }
+        instance.validate(raQrCode1).type shouldBe CoronaTest.Type.RAPID_ANTIGEN
+        verify { raExtractor.extract(raQrCode1, Mode.TEST_STRICT) }
+    }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/qrcode/PcrQrCodeExtractorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/qrcode/PcrQrCodeExtractorTest.kt
index e4537ff5a6113f3d0c46a6691851bdf94a3a9a69..86e1812719a3d4b1289a23f9568f14f8adc72833 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/qrcode/PcrQrCodeExtractorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/qrcode/PcrQrCodeExtractorTest.kt
@@ -1,5 +1,6 @@
 package de.rki.coronawarnapp.coronatest.qrcode
 
+import de.rki.coronawarnapp.coronatest.qrcode.QrCodeExtractor.Mode.TEST_STRICT
 import io.kotest.matchers.shouldBe
 import org.junit.Test
 import testhelpers.BaseTest
@@ -16,7 +17,7 @@ class PcrQrCodeExtractorTest : BaseTest() {
         val extractor = PcrQrCodeExtractor()
         try {
             if (extractor.canHandle("$prefixString$guid")) {
-                extractor.extract("$prefixString$guid")
+                extractor.extract("$prefixString$guid", mode = TEST_STRICT)
                 conditionToMatch shouldBe true
             } else {
                 conditionToMatch shouldBe false
@@ -77,16 +78,43 @@ class PcrQrCodeExtractorTest : BaseTest() {
 
     @Test
     fun extractGUID() {
-        PcrQrCodeExtractor().extract("$localhostUpperCase$guidUpperCase").qrCodeGUID shouldBe guidUpperCase
-        PcrQrCodeExtractor().extract("$localhostUpperCase$guidLowerCase").qrCodeGUID shouldBe guidLowerCase
-        PcrQrCodeExtractor().extract("$localhostUpperCase$guidMixedCase").qrCodeGUID shouldBe guidMixedCase
+        PcrQrCodeExtractor().extract(
+            "$localhostUpperCase$guidUpperCase",
+            mode = TEST_STRICT
+        ).qrCodeGUID shouldBe guidUpperCase
+        PcrQrCodeExtractor().extract(
+            "$localhostUpperCase$guidLowerCase",
+            mode = TEST_STRICT
+        ).qrCodeGUID shouldBe guidLowerCase
+        PcrQrCodeExtractor().extract(
+            "$localhostUpperCase$guidMixedCase",
+            mode = TEST_STRICT
+        ).qrCodeGUID shouldBe guidMixedCase
 
-        PcrQrCodeExtractor().extract("$localhostLowerCase$guidUpperCase").qrCodeGUID shouldBe guidUpperCase
-        PcrQrCodeExtractor().extract("$localhostLowerCase$guidLowerCase").qrCodeGUID shouldBe guidLowerCase
-        PcrQrCodeExtractor().extract("$localhostLowerCase$guidMixedCase").qrCodeGUID shouldBe guidMixedCase
+        PcrQrCodeExtractor().extract(
+            "$localhostLowerCase$guidUpperCase",
+            mode = TEST_STRICT
+        ).qrCodeGUID shouldBe guidUpperCase
+        PcrQrCodeExtractor().extract(
+            "$localhostLowerCase$guidLowerCase",
+            mode = TEST_STRICT
+        ).qrCodeGUID shouldBe guidLowerCase
+        PcrQrCodeExtractor().extract(
+            "$localhostLowerCase$guidMixedCase",
+            mode = TEST_STRICT
+        ).qrCodeGUID shouldBe guidMixedCase
 
-        PcrQrCodeExtractor().extract("$localhostMixedCase$guidUpperCase").qrCodeGUID shouldBe guidUpperCase
-        PcrQrCodeExtractor().extract("$localhostMixedCase$guidLowerCase").qrCodeGUID shouldBe guidLowerCase
-        PcrQrCodeExtractor().extract("$localhostMixedCase$guidMixedCase").qrCodeGUID shouldBe guidMixedCase
+        PcrQrCodeExtractor().extract(
+            "$localhostMixedCase$guidUpperCase",
+            mode = TEST_STRICT
+        ).qrCodeGUID shouldBe guidUpperCase
+        PcrQrCodeExtractor().extract(
+            "$localhostMixedCase$guidLowerCase",
+            mode = TEST_STRICT
+        ).qrCodeGUID shouldBe guidLowerCase
+        PcrQrCodeExtractor().extract(
+            "$localhostMixedCase$guidMixedCase",
+            mode = TEST_STRICT
+        ).qrCodeGUID shouldBe guidMixedCase
     }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/qrcode/RapidAntigenQrCodeExtractorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/qrcode/RapidAntigenQrCodeExtractorTest.kt
index e78658b69175283df92b1e3ebb58182c62749a61..4a746b6edd43282f85b60c2a88039eb7194f42e4 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/qrcode/RapidAntigenQrCodeExtractorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/qrcode/RapidAntigenQrCodeExtractorTest.kt
@@ -1,5 +1,6 @@
 package de.rki.coronawarnapp.coronatest.qrcode
 
+import de.rki.coronawarnapp.coronatest.qrcode.QrCodeExtractor.Mode.TEST_STRICT
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
 import io.kotest.assertions.throwables.shouldThrow
 import io.kotest.matchers.shouldBe
@@ -29,13 +30,13 @@ class RapidAntigenQrCodeExtractorTest : BaseTest() {
     @Test
     fun `extracting valid codes does not throw exception`() {
         listOf(raQrCode1, raQrCode2, raQrCode3, raQrCode4, raQrCode5, raQrCode6, raQrCode7, raQrCode8).forEach {
-            instance.extract(it)
+            instance.extract(it, mode = TEST_STRICT)
         }
     }
 
     @Test
     fun `personal data is extracted`() {
-        val data = instance.extract(raQrCode3)
+        val data = instance.extract(raQrCode3, mode = TEST_STRICT)
         data.type shouldBe CoronaTest.Type.RAPID_ANTIGEN
         data.hash shouldBe "7dce08db0d4abd5ac1d2498b571afb221ca947c75c847d05466b4cfe9d95dc66"
         data.createdAt shouldBe Instant.ofEpochMilli(1619618352000)
@@ -46,7 +47,7 @@ class RapidAntigenQrCodeExtractorTest : BaseTest() {
 
     @Test
     fun `empty strings are treated as null or notset`() {
-        val data = instance.extract(raQrCodeEmptyStrings)
+        val data = instance.extract(raQrCodeEmptyStrings, mode = TEST_STRICT)
         data.type shouldBe CoronaTest.Type.RAPID_ANTIGEN
         data.hash shouldBe "d6e4d0181d8109bf05b346a0d2e0ef0cc472eed70d9df8c4b9ae5c7a009f3e34"
         data.createdAt shouldBe Instant.ofEpochMilli(1619012952000)
@@ -57,14 +58,14 @@ class RapidAntigenQrCodeExtractorTest : BaseTest() {
 
     @Test
     fun `personal data is only valid if complete or completely missing`() {
-        shouldThrow<InvalidQRCodeException> { instance.extract(raQrIncompletePersonalData) }
+        shouldThrow<InvalidQRCodeException> { instance.extract(raQrIncompletePersonalData, mode = TEST_STRICT) }
     }
 
     @Test
     fun `invalid json throws exception`() {
         val invalidCode = "https://s.coronawarn.app/?v=1#eyJ0aW1lc3RhbXAiOjE2"
         shouldThrow<InvalidQRCodeException> {
-            RapidAntigenQrCodeExtractor().extract(invalidCode)
+            RapidAntigenQrCodeExtractor().extract(invalidCode, mode = TEST_STRICT)
         }
     }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/VaccinationTestComponent.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/VaccinationTestComponent.kt
index 181970bd621adbbc1eb156126f6bd70dcbd01dd7..7f80b1fbbe61087271d832cd31c1776329589f71 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/VaccinationTestComponent.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/VaccinationTestComponent.kt
@@ -4,6 +4,7 @@ import dagger.Component
 import dagger.Module
 import de.rki.coronawarnapp.util.serialization.SerializationModule
 import de.rki.coronawarnapp.vaccination.core.qrcode.VaccinationQRCodeExtractorTest
+import de.rki.coronawarnapp.vaccination.core.qrcode.VaccinationQrCodeValidatorTest
 import de.rki.coronawarnapp.vaccination.core.repository.VaccinationRepositoryTest
 import de.rki.coronawarnapp.vaccination.core.repository.storage.VaccinationContainerTest
 import de.rki.coronawarnapp.vaccination.core.repository.storage.VaccinationStorageTest
@@ -23,6 +24,7 @@ interface VaccinationTestComponent {
     fun inject(testClass: VaccinationQRCodeExtractorTest)
     fun inject(testClass: VaccinatedPersonTest)
     fun inject(testClass: VaccinationRepositoryTest)
+    fun inject(testClass: VaccinationQrCodeValidatorTest)
 
     @Component.Factory
     interface Factory {
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/VaccinationTestData.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/VaccinationTestData.kt
index 0c5117d63094019d089ac68493a1edd962fda0cf..9ff6c95e55f6186c6067a56e6018911787da5e71 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/VaccinationTestData.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/VaccinationTestData.kt
@@ -184,4 +184,14 @@ class VaccinationTestData @Inject constructor(
     ).apply {
         qrCodeExtractor = this@VaccinationTestData.qrCodeExtractor
     }
+
+    val personYVacTwoEntriesQrCode =
+        "HC1:6BFOXN%TSMAHN-HVN8J7UQMJ4/36 L-AHQ+R1WG%MP8*ICG5QKM0658WAULO8NASA3/-2E%5G%5TW5A 6YO6XL6Q3QR\$P*NI92KV6TKOJ06JYZJV1JJ7UGOJUTIJ7J:ZJ83BL8TFVTV9T.ZJC0J*PIZ.TJ STPT*IJ5OI9YI:8DJ:D%PDDIKIWCHAB.YMAHLW 70SO:GOLIROGO3T59YLY1S7HOPC5NDOEC5/64ND7BT5PE4D/5:/6N9R%EPXCROGO+GOVIR-PQ395R4IUHLW\$G-B5ET42HPPEPHCR6W97DON95N14Q6SP+PJD1W9L \$N3-Q.VBAO8MN9*QHAO96Y2/*13A5-8E6V59I9BZK6:IZW4I:A6J3ARN QT1BGL4OMJKR.K\$A1EB14UVC2O+5T3.CE1M33KS2JKA8Y*99CCLLOR/CH0GRP8 GLY 1LA7551DC2U.NVOTJOII:8DKEK%N92T9YQ$0MK%P6\$G9K7QQUY9KI.EK*8XRS-DPA5W64SMVR1NF6D0 2S0.7R:ASENTI094PIDS:T32DRE8N"
+
+    val personYVacTwoEntriesContainer = VaccinationContainer(
+        scannedAt = Instant.ofEpochMilli(1620062834471),
+        vaccinationQrCode = personYVacTwoEntriesQrCode,
+    ).apply {
+        qrCodeExtractor = this@VaccinationTestData.qrCodeExtractor
+    }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/qrcode/VaccinationQRCodeExtractorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/qrcode/VaccinationQRCodeExtractorTest.kt
index 1b41ddfa08b51bae20ea21a7186b1c8d32ca7564..0c7670d9aef4c687f1d56a9cf1190ae3cfd6f668 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/qrcode/VaccinationQRCodeExtractorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/qrcode/VaccinationQRCodeExtractorTest.kt
@@ -1,5 +1,6 @@
 package de.rki.coronawarnapp.vaccination.core.qrcode
 
+import de.rki.coronawarnapp.coronatest.qrcode.QrCodeExtractor.Mode
 import de.rki.coronawarnapp.vaccination.core.DaggerVaccinationTestComponent
 import de.rki.coronawarnapp.vaccination.core.VaccinationQrCodeTestData
 import de.rki.coronawarnapp.vaccination.core.VaccinationTestData
@@ -29,17 +30,17 @@ class VaccinationQRCodeExtractorTest : BaseTest() {
 
     @Test
     fun `happy path extraction`() {
-        extractor.extract(VaccinationQrCodeTestData.validVaccinationQrCode)
+        extractor.extract(VaccinationQrCodeTestData.validVaccinationQrCode, mode = Mode.CERT_VAC_STRICT)
     }
 
     @Test
     fun `happy path extraction 2`() {
-        extractor.extract(VaccinationQrCodeTestData.validVaccinationQrCode2)
+        extractor.extract(VaccinationQrCodeTestData.validVaccinationQrCode2, mode = Mode.CERT_VAC_STRICT)
     }
 
     @Test
     fun `happy path extraction with data`() {
-        val qrCode = extractor.extract(VaccinationQrCodeTestData.validVaccinationQrCode3)
+        val qrCode = extractor.extract(VaccinationQrCodeTestData.validVaccinationQrCode3, mode = Mode.CERT_VAC_STRICT)
 
         with(qrCode.parsedData.header) {
             issuer shouldBe "AT"
@@ -76,52 +77,76 @@ class VaccinationQRCodeExtractorTest : BaseTest() {
 
     @Test
     fun `happy path extraction 4`() {
-        extractor.extract(VaccinationQrCodeTestData.validVaccinationQrCode4)
+        extractor.extract(
+            VaccinationQrCodeTestData.validVaccinationQrCode4,
+            mode = Mode.CERT_VAC_STRICT
+        )
     }
 
     @Test
     fun `valid encoding but not a health certificate fails with VC_HC_CWT_NO_ISS`() {
         shouldThrow<InvalidHealthCertificateException> {
-            extractor.extract(VaccinationQrCodeTestData.validEncoded)
+            extractor.extract(
+                VaccinationQrCodeTestData.validEncoded,
+                mode = Mode.CERT_VAC_STRICT
+            )
         }.errorCode shouldBe VC_HC_CWT_NO_ISS
     }
 
     @Test
     fun `random string fails with HC_BASE45_DECODING_FAILED`() {
         shouldThrow<InvalidHealthCertificateException> {
-            extractor.extract("nothing here to see")
+            extractor.extract(
+                "nothing here to see",
+                mode = Mode.CERT_VAC_STRICT
+            )
         }.errorCode shouldBe HC_BASE45_DECODING_FAILED
     }
 
     @Test
     fun `uncompressed base45 string fails with HC_ZLIB_DECOMPRESSION_FAILED`() {
         shouldThrow<InvalidHealthCertificateException> {
-            extractor.extract("6BFOABCDEFGHIJKLMNOPQRSTUVWXYZ %*+-./:")
+            extractor.extract(
+                "6BFOABCDEFGHIJKLMNOPQRSTUVWXYZ %*+-./:",
+                mode = Mode.CERT_VAC_STRICT
+            )
         }.errorCode shouldBe HC_ZLIB_DECOMPRESSION_FAILED
     }
 
     @Test
     fun `vaccination certificate missing fails with VC_NO_VACCINATION_ENTRY`() {
         shouldThrow<InvalidHealthCertificateException> {
-            extractor.extract(VaccinationQrCodeTestData.certificateMissing)
+            extractor.extract(
+                VaccinationQrCodeTestData.certificateMissing,
+                mode = Mode.CERT_VAC_STRICT
+            )
         }.errorCode shouldBe VC_NO_VACCINATION_ENTRY
     }
 
     @Test
     fun `test data person A check`() {
-        val extracted = extractor.extract(vaccinationTestData.personAVac1QRCodeString)
+        val extracted = extractor.extract(
+            vaccinationTestData.personAVac1QRCodeString,
+            mode = Mode.CERT_VAC_STRICT
+        )
         extracted shouldBe vaccinationTestData.personAVac1QRCode
     }
 
     @Test
     fun `test data person B check`() {
-        val extracted = extractor.extract(vaccinationTestData.personBVac1QRCodeString)
+        val extracted = extractor.extract(
+            vaccinationTestData.personBVac1QRCodeString,
+            mode = Mode.CERT_VAC_STRICT
+        )
         extracted shouldBe vaccinationTestData.personBVac1QRCode
     }
 
     @Test
     fun `Bulgarian qr code passes`() {
-        val qrCode = extractor.extract(VaccinationQrCodeTestData.qrCodeBulgaria)
+        val qrCode = extractor.extract(
+            VaccinationQrCodeTestData.qrCodeBulgaria,
+            mode = Mode.CERT_VAC_STRICT
+        )
         with(qrCode.parsedData.header) {
             issuer shouldBe "BG"
             issuedAt shouldBe Instant.parse("2021-06-02T14:07:56.000Z")
@@ -157,6 +182,9 @@ class VaccinationQRCodeExtractorTest : BaseTest() {
 
     @Test
     fun `Swedish qr code passes`() {
-        extractor.extract(VaccinationQrCodeTestData.qrCodeSweden)
+        extractor.extract(
+            VaccinationQrCodeTestData.qrCodeSweden,
+            mode = Mode.CERT_VAC_STRICT
+        )
     }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/qrcode/VaccinationQrCodeValidatorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/qrcode/VaccinationQrCodeValidatorTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9c08a3e0e4a1350d0ecce4a851118675ef1f187b
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/qrcode/VaccinationQrCodeValidatorTest.kt
@@ -0,0 +1,34 @@
+package de.rki.coronawarnapp.vaccination.core.qrcode
+
+import de.rki.coronawarnapp.coronatest.qrcode.QrCodeExtractor.Mode
+import de.rki.coronawarnapp.vaccination.core.DaggerVaccinationTestComponent
+import de.rki.coronawarnapp.vaccination.core.VaccinationTestData
+import io.kotest.matchers.shouldBe
+import io.mockk.spyk
+import io.mockk.verify
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import testhelpers.BaseTest
+import javax.inject.Inject
+
+class VaccinationQrCodeValidatorTest : BaseTest() {
+    @Inject lateinit var testData: VaccinationTestData
+    @Inject lateinit var vacExtractor: VaccinationQRCodeExtractor
+    private lateinit var vacExtractorSpy: VaccinationQRCodeExtractor
+
+    @BeforeEach
+    fun setup() {
+        DaggerVaccinationTestComponent.factory().create().inject(this)
+
+        vacExtractorSpy = spyk(vacExtractor)
+    }
+
+    @Test
+    fun `validator uses strict extraction mode`() {
+        val instance = VaccinationQRCodeValidator(vacExtractorSpy)
+        instance.validate(testData.personAVac1QRCodeString).apply {
+            uniqueCertificateIdentifier shouldBe testData.personAVac1Container.certificateId
+        }
+        verify { vacExtractorSpy.extract(testData.personAVac1QRCodeString, Mode.CERT_VAC_STRICT) }
+    }
+}
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/repository/storage/VaccinationContainerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/repository/storage/VaccinationContainerTest.kt
index fad39f683f0e946dda8f94afb044c82a403a554d..a2817d54405fe05efeeeb2e6272d38603961f6ae 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/repository/storage/VaccinationContainerTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/repository/storage/VaccinationContainerTest.kt
@@ -1,12 +1,17 @@
 package de.rki.coronawarnapp.vaccination.core.repository.storage
 
+import de.rki.coronawarnapp.coronatest.qrcode.QrCodeExtractor
 import de.rki.coronawarnapp.vaccination.core.DaggerVaccinationTestComponent
 import de.rki.coronawarnapp.vaccination.core.VaccinatedPersonIdentifier
 import de.rki.coronawarnapp.vaccination.core.VaccinationTestData
+import de.rki.coronawarnapp.vaccination.core.qrcode.VaccinationCertificateQRCode
+import de.rki.coronawarnapp.vaccination.core.qrcode.VaccinationQRCodeExtractor
 import de.rki.coronawarnapp.vaccination.core.server.valueset.VaccinationValueSet
 import io.kotest.matchers.shouldBe
+import io.kotest.matchers.shouldNotBe
 import io.mockk.every
 import io.mockk.mockk
+import io.mockk.verify
 import org.joda.time.Instant
 import org.joda.time.LocalDate
 import org.junit.jupiter.api.BeforeEach
@@ -138,4 +143,27 @@ class VaccinationContainerTest : BaseTest() {
             certificateCountry shouldBe "YY"
         }
     }
+
+    @Test
+    fun `default parsing mode for containers is lenient`() {
+        val container = VaccinationContainer(
+            vaccinationQrCode = testData.personYVacTwoEntriesQrCode,
+            scannedAt = Instant.EPOCH
+        )
+        val extractor = mockk<VaccinationQRCodeExtractor>().apply {
+            every { extract(any(), any()) } returns mockk<VaccinationCertificateQRCode>().apply {
+                every { parsedData } returns mockk()
+            }
+        }
+        container.qrCodeExtractor = extractor
+
+        container.certificateData shouldNotBe null
+
+        verify { extractor.extract(testData.personYVacTwoEntriesQrCode, QrCodeExtractor.Mode.CERT_VAC_LENIENT) }
+    }
+
+    @Test
+    fun `gracefully handle semi invalid data - multiple entries`() {
+        testData.personYVacTwoEntriesContainer.certificate.vaccinationDatas.size shouldBe 1
+    }
 }