diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/debugoptions/ui/DebugOptionsFragment.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/debugoptions/ui/DebugOptionsFragment.kt
index 1c1441fb24dba0532ac10ff9c8f31bb9695f4b4e..b0e02bfce947e3a0776b4ed9eca95af2ca08d524 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/debugoptions/ui/DebugOptionsFragment.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/debugoptions/ui/DebugOptionsFragment.kt
@@ -71,7 +71,6 @@ class DebugOptionsFragment : Fragment(R.layout.fragment_test_debugoptions), Auto
                 environmentCdnurlVerification.text = "Verification CDN:\n${state.urlVerification}"
                 environmentUrlDatadonation.text = "DataDonation:\n${state.urlDataDonation}"
                 environmentUrlLogUpload.text = "LogUpload:\n${state.urlLogUpload}"
-                environmentCdnUrlVaccination.text = "Vaccination CDN: \n${state.urlVaccination}"
                 environmentPubkeyCrowdnotifier.text = "CrowdNotifierPubKey:\n${state.pubKeyCrowdNotifier}"
                 environmentPubkeyAppconfig.text = "AppConfigPubKey:\n${state.pubKeyAppConfig}"
             }
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/debugoptions/ui/EnvironmentState.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/debugoptions/ui/EnvironmentState.kt
index 604996995a54bc7ef8e0e241e677d3588afa17ce..c9b907793ab6812a252f519c71a9bee66af2387a 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/debugoptions/ui/EnvironmentState.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/debugoptions/ui/EnvironmentState.kt
@@ -10,7 +10,6 @@ data class EnvironmentState(
     val urlVerification: String,
     val urlDataDonation: String,
     val urlLogUpload: String,
-    val urlVaccination: String,
     val pubKeyCrowdNotifier: String,
     val pubKeyAppConfig: String,
 ) {
@@ -23,7 +22,6 @@ data class EnvironmentState(
             urlVerification = verificationCdnUrl,
             urlDataDonation = dataDonationCdnUrl,
             urlLogUpload = logUploadServerUrl,
-            urlVaccination = vaccinationCdnUrl,
             pubKeyCrowdNotifier = crowdNotifierPublicKey,
             pubKeyAppConfig = appConfigPublicKey,
         )
diff --git a/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_debugoptions.xml b/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_debugoptions.xml
index 60061a05c16fe75d0af8856d12ffec4d6388853b..165e76a5873ac28d6015f1d63ec99802ff2c4a4f 100644
--- a/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_debugoptions.xml
+++ b/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_debugoptions.xml
@@ -109,14 +109,6 @@
                     android:layout_marginTop="4dp"
                     tools:text="LogUpload: ?" />
 
-                <TextView
-                    android:id="@+id/environment_cdn_url_vaccination"
-                    style="@style/TextAppearance.MaterialComponents.Caption"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="4dp"
-                    tools:text="Vaccination: ?" />
-
                 <TextView
                     android:id="@+id/environment_pubkey_appconfig"
                     style="@style/TextAppearance.MaterialComponents.Caption"
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/EnvironmentModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/EnvironmentModule.kt
index 3a81cb926a78ecec4b9f6e8333b31fb15e075770..b99710e6d4a6bd5a07a5bb7d08931aecf4594746 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/EnvironmentModule.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/EnvironmentModule.kt
@@ -5,7 +5,6 @@ import de.rki.coronawarnapp.environment.bugreporting.BugReportingServerModule
 import de.rki.coronawarnapp.environment.datadonation.DataDonationCDNModule
 import de.rki.coronawarnapp.environment.download.DownloadCDNModule
 import de.rki.coronawarnapp.environment.submission.SubmissionCDNModule
-import de.rki.coronawarnapp.environment.vaccination.VaccinationCertificateUrlModule
 import de.rki.coronawarnapp.environment.verification.VerificationCDNModule
 
 @Module(
@@ -14,8 +13,7 @@ import de.rki.coronawarnapp.environment.verification.VerificationCDNModule
         SubmissionCDNModule::class,
         VerificationCDNModule::class,
         DataDonationCDNModule::class,
-        BugReportingServerModule::class,
-        VaccinationCertificateUrlModule::class
+        BugReportingServerModule::class
     ]
 )
 class EnvironmentModule
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/EnvironmentSetup.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/EnvironmentSetup.kt
index f7d1a754da9017d98a45bc58ac599d469a978082..d44e8e88ef378eaae6e78f7c4e73591be7c08e93 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/EnvironmentSetup.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/EnvironmentSetup.kt
@@ -12,7 +12,6 @@ import de.rki.coronawarnapp.environment.EnvironmentSetup.EnvKey.LOG_UPLOAD
 import de.rki.coronawarnapp.environment.EnvironmentSetup.EnvKey.SAFETYNET_API_KEY
 import de.rki.coronawarnapp.environment.EnvironmentSetup.EnvKey.SUBMISSION
 import de.rki.coronawarnapp.environment.EnvironmentSetup.EnvKey.USE_EUR_KEY_PKGS
-import de.rki.coronawarnapp.environment.EnvironmentSetup.EnvKey.VACCINATION_VALUE
 import de.rki.coronawarnapp.environment.EnvironmentSetup.EnvKey.VERIFICATION
 import de.rki.coronawarnapp.environment.EnvironmentSetup.EnvKey.VERIFICATION_KEYS
 import de.rki.coronawarnapp.environment.EnvironmentSetup.Type.Companion.toEnvironmentType
@@ -37,7 +36,6 @@ class EnvironmentSetup @Inject constructor(
         VERIFICATION_KEYS("PUB_KEYS_SIGNATURE_VERIFICATION"),
         DATA_DONATION("DATA_DONATION_CDN_URL"),
         LOG_UPLOAD("LOG_UPLOAD_SERVER_URL"),
-        VACCINATION_VALUE("VACCINATION_CDN_URL"),
         SAFETYNET_API_KEY("SAFETYNET_API_KEY"),
         CROWD_NOTIFIER_PUBLIC_KEY("CROWD_NOTIFIER_PUBLIC_KEY")
     }
@@ -137,9 +135,6 @@ class EnvironmentSetup @Inject constructor(
     val logUploadServerUrl: String
         get() = getEnvironmentValue(LOG_UPLOAD).asString
 
-    val vaccinationCdnUrl: String
-        get() = getEnvironmentValue(VACCINATION_VALUE).asString
-
     companion object {
         private const val PKEY_CURRENT_ENVINROMENT = "environment.current"
     }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/vaccination/VaccinationCertificateCDNUrl.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/vaccination/VaccinationCertificateCDNUrl.kt
deleted file mode 100644
index 5740f4bf0ca8e587642020e693a8754b43e91b09..0000000000000000000000000000000000000000
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/vaccination/VaccinationCertificateCDNUrl.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-package de.rki.coronawarnapp.environment.vaccination
-
-import javax.inject.Qualifier
-
-@Qualifier
-@MustBeDocumented
-@Retention(AnnotationRetention.RUNTIME)
-annotation class VaccinationCertificateCDNUrl
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/vaccination/VaccinationCertificateUrlModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/vaccination/VaccinationCertificateUrlModule.kt
deleted file mode 100644
index 5660c7604074271c317ccd556e911bf78de18bb6..0000000000000000000000000000000000000000
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/vaccination/VaccinationCertificateUrlModule.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package de.rki.coronawarnapp.environment.vaccination
-
-import dagger.Module
-import dagger.Provides
-import dagger.Reusable
-import de.rki.coronawarnapp.environment.BaseEnvironmentModule
-import de.rki.coronawarnapp.environment.EnvironmentSetup
-
-@Module
-class VaccinationCertificateUrlModule : BaseEnvironmentModule() {
-
-    @Reusable
-    @VaccinationCertificateCDNUrl
-    @Provides
-    fun provideVaccinationValueSetUrl(environmentSetup: EnvironmentSetup): String =
-        requireValidUrl(environmentSetup.vaccinationCdnUrl)
-}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/repository/ValueSetsRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/repository/ValueSetsRepository.kt
index ca5f244a11c0785cd63b06bede6576f00c49579a..27de6bffab3d6d14dd588f322d370025b3efdb51 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/repository/ValueSetsRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/repository/ValueSetsRepository.kt
@@ -1,18 +1,16 @@
 package de.rki.coronawarnapp.vaccination.core.repository
 
+import androidx.annotation.VisibleForTesting
 import dagger.Reusable
 import de.rki.coronawarnapp.util.coroutine.AppScope
 import de.rki.coronawarnapp.vaccination.core.repository.storage.ValueSetsStorage
-import de.rki.coronawarnapp.vaccination.core.server.valueset.DefaultVaccinationValueSet
 import de.rki.coronawarnapp.vaccination.core.server.valueset.VaccinationServer
 import de.rki.coronawarnapp.vaccination.core.server.valueset.VaccinationValueSet
+import de.rki.coronawarnapp.vaccination.core.server.valueset.isEmpty
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.filterNotNull
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.launch
 import timber.log.Timber
 import java.util.Locale
 import javax.inject.Inject
@@ -21,57 +19,55 @@ import javax.inject.Inject
 class ValueSetsRepository @Inject constructor(
     private val vaccinationServer: VaccinationServer,
     private val valueSetsStorage: ValueSetsStorage,
-    @AppScope appScope: CoroutineScope
+    @AppScope private val scope: CoroutineScope
 ) {
 
-    private val internalFlow = MutableStateFlow<Locale?>(null)
+    val latestValueSet: Flow<VaccinationValueSet> = valueSetsStorage.valueSet.flow.distinctUntilChanged()
 
-    val latestValueSet: Flow<VaccinationValueSet?> = internalFlow
-        .filterNotNull()
-        .map {
-            fromServer(it) ?: fromLocalStorage() ?: fromServer(Locale.ENGLISH) ?: createEmptyValueSet(it)
-            // Return empty value set as last resort
-        }
-        .stateIn(
-            scope = appScope,
-            started = SharingStarted.Lazily,
-            initialValue = createEmptyValueSet(Locale.ENGLISH)
-        )
-
-    fun reloadValueSet(languageCode: Locale) {
-        Timber.d("reloadValueSet(languageCode=%s)", languageCode)
-        internalFlow.value = languageCode
-    }
+    fun triggerUpdateValueSet(languageCode: Locale) = scope.launch {
+        Timber.d("triggerUpdateValueSet(languageCode=%s)", languageCode)
+        var valueSet = vaccinationServer.getVaccinationValueSets(languageCode = languageCode)
 
-    private suspend fun fromServer(languageCode: Locale): VaccinationValueSet? = try {
-        Timber.d("fromServer(languageCode=%s)", languageCode)
-        vaccinationServer.getVaccinationValueSets(languageCode = languageCode)?.also {
-            Timber.d("Saving new value sets %s", it)
-            valueSetsStorage.vaccinationValueSet = it
+        if (valueSet == null && valueSetsStorage.valueSet.value.isEmpty()) {
+            Timber.d(
+                "Got no value set from server for %s and local value set is empty... " +
+                    "Try fallback to value set for en",
+                languageCode.language
+            )
+            valueSet = vaccinationServer.getVaccinationValueSets(languageCode = Locale.ENGLISH)
         }
-    } catch (e: Exception) {
-        Timber.w(e, "fromServer(): %s", e.message)
-        null
-    }
 
-    private fun fromLocalStorage(): VaccinationValueSet? = try {
-        Timber.d("fromLocalStorage()")
-        valueSetsStorage.vaccinationValueSet
-    } catch (e: Exception) {
-        Timber.w(e, "fromLocalStorage(): %s", e.message)
-        null
+        valueSet
+            .also { Timber.d("Value set is %s", it) }
+            ?.let { newValueSet -> valueSetsStorage.valueSet.update { newValueSet.toStoredVaccinationValueSet() } }
     }
 
-    private fun createEmptyValueSet(languageCode: Locale) = DefaultVaccinationValueSet(
-        languageCode = languageCode,
-        vp = DefaultVaccinationValueSet.DefaultValueSet(items = emptyList()),
-        mp = DefaultVaccinationValueSet.DefaultValueSet(items = emptyList()),
-        ma = DefaultVaccinationValueSet.DefaultValueSet(items = emptyList())
-    )
-
     fun clear() {
         Timber.d("Clearing value sets")
         vaccinationServer.clear()
         valueSetsStorage.clear()
     }
 }
+
+@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+fun VaccinationValueSet.toStoredVaccinationValueSet(): ValueSetsStorage.StoredVaccinationValueSet =
+    ValueSetsStorage.StoredVaccinationValueSet(
+        languageCode = languageCode,
+        vp = vp.toStoredValueSet(),
+        mp = mp.toStoredValueSet(),
+        ma = ma.toStoredValueSet()
+    )
+
+@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+fun VaccinationValueSet.ValueSet.toStoredValueSet(): ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet =
+    ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet(
+        items = items.map { it.toStoredItem() }
+    )
+
+@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+fun VaccinationValueSet.ValueSet.Item.toStoredItem():
+    ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet.StoredItem =
+        ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet.StoredItem(
+            key = key,
+            displayText = displayText
+        )
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/repository/storage/ValueSetsStorage.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/repository/storage/ValueSetsStorage.kt
index e9d91b475b72a8d521cbf6e649407bc7f7c08f4d..bb81b8a8261a55e8bfa6cdcba1ed2f20ecb86064 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/repository/storage/ValueSetsStorage.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/repository/storage/ValueSetsStorage.kt
@@ -3,12 +3,13 @@ package de.rki.coronawarnapp.vaccination.core.repository.storage
 import android.content.Context
 import android.content.SharedPreferences
 import androidx.annotation.Keep
-import androidx.core.content.edit
 import com.google.gson.Gson
 import com.google.gson.annotations.SerializedName
 import dagger.Reusable
 import de.rki.coronawarnapp.util.di.AppContext
+import de.rki.coronawarnapp.util.preferences.FlowPreference
 import de.rki.coronawarnapp.util.preferences.clearAndNotify
+import de.rki.coronawarnapp.util.preferences.createFlowPreference
 import de.rki.coronawarnapp.util.serialization.BaseGson
 import de.rki.coronawarnapp.vaccination.core.server.valueset.VaccinationValueSet
 import timber.log.Timber
@@ -25,36 +26,26 @@ class ValueSetsStorage @Inject constructor(
         context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
     }
 
-    var vaccinationValueSet: VaccinationValueSet?
-        get() = getValueSet()
-        set(value) = setValueSet(value)
-
-    private fun getValueSet(): VaccinationValueSet? {
-        Timber.d("Loading value set")
-        return prefs.getString(PKEY_VALUE_SETS_PREFIX, null)?.let {
-            gson.fromJson(it, StoredVaccinationValueSet::class.java).also { loaded -> Timber.d("Loaded %s", loaded) }
-        }.also { Timber.d("Returning %s", it) }
-    }
-
-    private fun setValueSet(value: VaccinationValueSet?) {
-        Timber.d("Saving %s", value)
-        value?.let {
-            prefs.edit {
-                val storeValue = it.toStoredVaccinationValueSet()
-                val json = gson.toJson(storeValue, StoredVaccinationValueSet::class.java)
-                Timber.d("String %s", json)
-                putString(PKEY_VALUE_SETS_PREFIX, json)
-            }
-        }
-    }
+    var valueSet: FlowPreference<StoredVaccinationValueSet> = prefs.createFlowPreference(
+        key = PKEY_VALUE_SETS_PREFIX,
+        reader = FlowPreference.gsonReader(gson = gson, createEmptyValueSet()),
+        writer = FlowPreference.gsonWriter(gson = gson)
+    )
 
     fun clear() {
         Timber.d("Clearing local storage")
         prefs.clearAndNotify()
     }
 
+    private fun createEmptyValueSet() = StoredVaccinationValueSet(
+        languageCode = Locale.ENGLISH,
+        vp = StoredVaccinationValueSet.StoredValueSet(items = emptyList()),
+        mp = StoredVaccinationValueSet.StoredValueSet(items = emptyList()),
+        ma = StoredVaccinationValueSet.StoredValueSet(items = emptyList())
+    )
+
     @Keep
-    private data class StoredVaccinationValueSet(
+    data class StoredVaccinationValueSet(
         @SerializedName("languageCode") override val languageCode: Locale,
         @SerializedName("vp") override val vp: StoredValueSet,
         @SerializedName("mp") override val mp: StoredValueSet,
@@ -73,26 +64,7 @@ class ValueSetsStorage @Inject constructor(
             ) : VaccinationValueSet.ValueSet.Item
         }
     }
-
-    private fun VaccinationValueSet.toStoredVaccinationValueSet(): StoredVaccinationValueSet =
-        StoredVaccinationValueSet(
-            languageCode = languageCode,
-            vp = vp.toStoredValueSet(),
-            mp = mp.toStoredValueSet(),
-            ma = ma.toStoredValueSet()
-        )
-
-    private fun VaccinationValueSet.ValueSet.toStoredValueSet(): StoredVaccinationValueSet.StoredValueSet =
-        StoredVaccinationValueSet.StoredValueSet(
-            items = items.map { it.toStoredItem() }
-        )
-
-    private fun VaccinationValueSet.ValueSet.Item.toStoredItem(): StoredVaccinationValueSet.StoredValueSet.StoredItem =
-        StoredVaccinationValueSet.StoredValueSet.StoredItem(
-            key = key,
-            displayText = displayText
-        )
 }
 
-private const val PREF_NAME = "valuesets_local"
-private const val PKEY_VALUE_SETS_PREFIX = "valuesets"
+private const val PREF_NAME = "valuesets_localdata"
+private const val PKEY_VALUE_SETS_PREFIX = "valueset"
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/server/valueset/VaccinationValueSet.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/server/valueset/VaccinationValueSet.kt
index 2ebc6e08a1f3ce0f9de7d1f0deeaa12ff9acebf2..08618fc008c487cd471b334a15fe6df1d039a348 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/server/valueset/VaccinationValueSet.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/server/valueset/VaccinationValueSet.kt
@@ -1,9 +1,7 @@
 package de.rki.coronawarnapp.vaccination.core.server.valueset
 
-import androidx.annotation.Keep
 import java.util.Locale
 
-@Keep
 interface VaccinationValueSet {
     val languageCode: Locale
     val vp: ValueSet
@@ -25,3 +23,7 @@ fun VaccinationValueSet.getDisplayText(key: String): String? =
     vp.getDisplayText(key) ?: mp.getDisplayText(key) ?: ma.getDisplayText(key)
 
 fun VaccinationValueSet.ValueSet.getDisplayText(key: String): String? = items.find { key == it.key }?.displayText
+
+fun VaccinationValueSet.isEmpty(): Boolean = vp.isEmpty() && mp.isEmpty() && ma.isEmpty()
+
+fun VaccinationValueSet.ValueSet.isEmpty(): Boolean = items.isEmpty()
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/server/valueset/VaccinationValueSetModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/server/valueset/VaccinationValueSetModule.kt
index 0fd80cda3bf80f09da0109692a134f4995a9ff1f..2b3413d14169f086392e7ab3df76a867f2acb57a 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/server/valueset/VaccinationValueSetModule.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/server/valueset/VaccinationValueSetModule.kt
@@ -25,7 +25,8 @@ class VaccinationValueSetModule {
     fun cache(
         @AppContext context: Context
     ): Cache {
-        val cacheDir = File(context.cacheDir, "vaccination_value")
+        val vaccDir = File(context.cacheDir, "vaccination")
+        val cacheDir = File(vaccDir, "valueset_httpcache")
         return Cache(cacheDir, CACHE_SIZE_5MB)
     }
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/VaccinationListViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/VaccinationListViewModel.kt
index 1a9e0d6ee0e6139ee189533c67dd3e080902c488..a4e200153ccea27b40c5e3422cd31964e594ff8f 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/VaccinationListViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/VaccinationListViewModel.kt
@@ -41,7 +41,7 @@ class VaccinationListViewModel @AssistedInject constructor(
 ) : CWAViewModel() {
 
     init {
-        valueSetsRepository.reloadValueSet(languageCode = context.getLocale())
+        valueSetsRepository.triggerUpdateValueSet(languageCode = context.getLocale())
     }
 
     val events = SingleLiveEvent<Event>()
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/environment/EnvironmentSetupTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/environment/EnvironmentSetupTest.kt
index 869893adae7cea43d461d87dd4b3ceb7001221db..12b178e9db9fd377c5eadcb406fb522a264d50e9 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/environment/EnvironmentSetupTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/environment/EnvironmentSetupTest.kt
@@ -68,7 +68,6 @@ class EnvironmentSetupTest : BaseTest() {
                 dataDonationCdnUrl shouldBe "https://datadonation-${env.rawKey}"
                 logUploadServerUrl shouldBe "https://logupload-${env.rawKey}"
                 crowdNotifierPublicKey shouldBe "123_abc-${env.rawKey}"
-                vaccinationCdnUrl shouldBe "https://vaccination-${env.rawKey}"
             }
         }
     }
@@ -128,8 +127,7 @@ class EnvironmentSetupTest : BaseTest() {
         EnvironmentSetup.EnvKey.LOG_UPLOAD.rawKey shouldBe "LOG_UPLOAD_SERVER_URL"
         EnvironmentSetup.EnvKey.SAFETYNET_API_KEY.rawKey shouldBe "SAFETYNET_API_KEY"
         EnvironmentSetup.EnvKey.CROWD_NOTIFIER_PUBLIC_KEY.rawKey shouldBe "CROWD_NOTIFIER_PUBLIC_KEY"
-        EnvironmentSetup.EnvKey.VACCINATION_VALUE.rawKey shouldBe "VACCINATION_CDN_URL"
-        EnvironmentSetup.EnvKey.values().size shouldBe 10
+        EnvironmentSetup.EnvKey.values().size shouldBe 9
     }
 
     companion object {
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/DataResetTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/DataResetTest.kt
index 5577560dc72f94ae8b79716c375227c270df1e73..3dbba9d531d6e633a583ac0c0e946e78a18fbb80 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/DataResetTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/DataResetTest.kt
@@ -131,6 +131,7 @@ internal class DataResetTest : BaseTest() {
             ratProfileSettings.deleteProfile()
             vaccinationRepository.clear()
             vaccinationPreferences.clear()
+            valueSetsRepository.clear()
         }
     }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/repository/ValueSetsRepositoryTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/repository/ValueSetsRepositoryTest.kt
index 3edc082661868d7de4748dcb8356778d988835a2..374831b938ca7e4384a0ad152b7c144bdf7b1766 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/repository/ValueSetsRepositoryTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/repository/ValueSetsRepositoryTest.kt
@@ -1,23 +1,26 @@
 package de.rki.coronawarnapp.vaccination.core.repository
 
+import de.rki.coronawarnapp.util.preferences.FlowPreference
 import de.rki.coronawarnapp.vaccination.core.repository.storage.ValueSetsStorage
 import de.rki.coronawarnapp.vaccination.core.server.valueset.DefaultVaccinationValueSet
 import de.rki.coronawarnapp.vaccination.core.server.valueset.VaccinationServer
+import de.rki.coronawarnapp.vaccination.core.server.valueset.VaccinationValueSet
 import io.kotest.matchers.shouldBe
 import io.mockk.MockKAnnotations
+import io.mockk.Ordering
 import io.mockk.coEvery
 import io.mockk.coVerify
 import io.mockk.every
 import io.mockk.impl.annotations.MockK
 import io.mockk.just
 import io.mockk.runs
-import io.mockk.verify
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.test.TestCoroutineScope
 import kotlinx.coroutines.test.runBlockingTest
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
 import testhelpers.BaseTest
+import testhelpers.preferences.mockFlowPreference
 import java.util.Locale
 
 class ValueSetsRepositoryTest : BaseTest() {
@@ -28,7 +31,8 @@ class ValueSetsRepositoryTest : BaseTest() {
     private val testScope = TestCoroutineScope()
 
     private val emptyValueSetEN = createValueSet(languageCode = Locale.ENGLISH)
-    private val emptyValueSetDE = createValueSet(languageCode = Locale.GERMAN)
+    private val valueSetPref: FlowPreference<ValueSetsStorage.StoredVaccinationValueSet> =
+        mockFlowPreference(emptyValueSetEN.toStoredVaccinationValueSet())
 
     private val valueSetEN = createValueSet(
         languageCode = Locale.ENGLISH,
@@ -89,125 +93,98 @@ class ValueSetsRepositoryTest : BaseTest() {
     private fun createInstance() = ValueSetsRepository(
         vaccinationServer = vaccinationServer,
         valueSetsStorage = valueSetsStorage,
-        appScope = testScope
+        scope = testScope
     )
 
     @BeforeEach
     fun setUp() {
         MockKAnnotations.init(this)
         coEvery { vaccinationServer.getVaccinationValueSets(any()) } returns null
+        coEvery { vaccinationServer.getVaccinationValueSets(languageCode = Locale.ENGLISH) } returns valueSetEN
+        coEvery { vaccinationServer.getVaccinationValueSets(languageCode = Locale.GERMAN) } returns valueSetDE
         every { vaccinationServer.clear() } just runs
-        every { valueSetsStorage.vaccinationValueSet } returns null
-        every { valueSetsStorage.vaccinationValueSet = any() } just runs
+
+        every { valueSetsStorage.valueSet } returns valueSetPref
         every { valueSetsStorage.clear() } just runs
     }
 
     @Test
-    fun `default value is an empty value set EN`() = runBlockingTest {
+    fun `successful update for de`() = runBlockingTest {
         createInstance().run {
-            latestValueSet.first() shouldBe emptyValueSetEN
+            triggerUpdateValueSet(languageCode = Locale.GERMAN)
+            latestValueSet.first()
+        }.also { it.validateValues(valueSetDE) }
 
-            coVerify(exactly = 0) {
-                vaccinationServer.getVaccinationValueSets(any())
-                valueSetsStorage.vaccinationValueSet
-            }
+        coVerify(exactly = 1) {
+            vaccinationServer.getVaccinationValueSets(languageCode = Locale.GERMAN)
         }
-    }
 
-    @Test
-    fun `falls back to empty value set with specified language code`() = runBlockingTest {
-        createInstance().run {
-            reloadValueSet(languageCode = Locale.GERMAN)
-            latestValueSet.first() shouldBe emptyValueSetDE
-
-            coVerify(exactly = 1) {
-                valueSetsStorage.vaccinationValueSet
-                vaccinationServer.getVaccinationValueSets(Locale.GERMAN)
-                vaccinationServer.getVaccinationValueSets(Locale.ENGLISH)
-            }
+        coVerify(exactly = 0) {
+            vaccinationServer.getVaccinationValueSets(languageCode = Locale.ENGLISH)
         }
     }
 
     @Test
-    fun `returns value set for specified language from server`() = runBlockingTest {
-        coEvery { vaccinationServer.getVaccinationValueSets(Locale.GERMAN) } returns valueSetDE
-        coEvery { vaccinationServer.getVaccinationValueSets(Locale.ENGLISH) } returns valueSetEN
-
+    fun `fallback to en`() = runBlockingTest {
         createInstance().run {
-            reloadValueSet(Locale.GERMAN)
-            latestValueSet.first() shouldBe valueSetDE
-
-            reloadValueSet(Locale.ENGLISH)
-            latestValueSet.first() shouldBe valueSetEN
-        }
+            triggerUpdateValueSet(languageCode = Locale.FRENCH)
+            latestValueSet.first()
+        }.also { it.validateValues(valueSetEN) }
 
-        verify(exactly = 0) {
-            valueSetsStorage.vaccinationValueSet
-        }
-
-        coVerify(exactly = 1) {
-            vaccinationServer.getVaccinationValueSets(Locale.GERMAN)
-            vaccinationServer.getVaccinationValueSets(Locale.ENGLISH)
+        coVerify(ordering = Ordering.ORDERED) {
+            vaccinationServer.getVaccinationValueSets(languageCode = Locale.FRENCH)
+            vaccinationServer.getVaccinationValueSets(languageCode = Locale.ENGLISH)
         }
     }
 
     @Test
-    fun `if no value set is available for specified language fall back to EN`() = runBlockingTest {
-        coEvery { vaccinationServer.getVaccinationValueSets(Locale.ENGLISH) } returns valueSetEN
+    fun `server returns nothing`() = runBlockingTest {
+        coEvery { vaccinationServer.getVaccinationValueSets(languageCode = Locale.GERMAN) } returns null
+        coEvery { vaccinationServer.getVaccinationValueSets(languageCode = Locale.ENGLISH) } returns null
 
         createInstance().run {
-            reloadValueSet(Locale.GERMAN)
-            latestValueSet.first() shouldBe valueSetEN
+            triggerUpdateValueSet(languageCode = Locale.GERMAN)
+            latestValueSet.first()
+        }.also { it.validateValues(emptyValueSetEN) }
 
-            coVerify(exactly = 1) {
-                vaccinationServer.getVaccinationValueSets(Locale.GERMAN)
-                vaccinationServer.getVaccinationValueSets(Locale.ENGLISH)
-            }
+        coVerify(ordering = Ordering.ORDERED) {
+            vaccinationServer.getVaccinationValueSets(languageCode = Locale.GERMAN)
+            vaccinationServer.getVaccinationValueSets(languageCode = Locale.ENGLISH)
         }
     }
 
     @Test
-    fun `use local storage if server returns nothing`() = runBlockingTest {
-        every { valueSetsStorage.vaccinationValueSet } returns valueSetDE
-
-        createInstance().run {
-            reloadValueSet(Locale.GERMAN)
-            latestValueSet.first() shouldBe valueSetDE
-
-            coVerify(exactly = 1) {
-                valueSetsStorage.vaccinationValueSet
-                vaccinationServer.getVaccinationValueSets(any())
-            }
-        }
+    fun `mapping is to stored version is correct`() {
+        valueSetDE.also { it.toStoredVaccinationValueSet().validateValues(it) }
+        valueSetEN.also { it.toStoredVaccinationValueSet().validateValues(it) }
+        emptyValueSetEN.also { it.toStoredVaccinationValueSet().validateValues(it) }
     }
 
     @Test
-    fun `user errors will not crash the app`() = runBlockingTest {
-        val userError = Exception("User error")
-        coEvery { vaccinationServer.getVaccinationValueSets(any()) } throws userError
-        every { valueSetsStorage.vaccinationValueSet } throws userError
-
+    fun `clear data of server and local storage`() {
         createInstance().run {
-            reloadValueSet(Locale.GERMAN)
-            latestValueSet.first() shouldBe emptyValueSetDE
+            clear()
 
             coVerify(exactly = 1) {
-                valueSetsStorage.vaccinationValueSet
-                vaccinationServer.getVaccinationValueSets(Locale.GERMAN)
-                vaccinationServer.getVaccinationValueSets(Locale.ENGLISH)
+                vaccinationServer.clear()
+                valueSetsStorage.clear()
             }
         }
     }
 
-    @Test
-    fun `clear() clears server and local storage`() {
-        createInstance().run {
-            clear()
+    private fun VaccinationValueSet.validateValues(v2: VaccinationValueSet) {
+        languageCode shouldBe v2.languageCode
+        vp.validateValues(v2.vp)
+        mp.validateValues(v2.mp)
+        ma.validateValues(v2.ma)
+    }
 
-            coVerify(exactly = 1) {
-                vaccinationServer.clear()
-                valueSetsStorage.clear()
-            }
+    private fun VaccinationValueSet.ValueSet.validateValues(v2: VaccinationValueSet.ValueSet) {
+        items.forEachIndexed { index, item1 ->
+            val item2 = v2.items[index]
+
+            item1.key shouldBe item2.key
+            item1.displayText shouldBe item2.displayText
         }
     }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/repository/storage/ValueSetsStorageTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/repository/storage/ValueSetsStorageTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..e333cef8a7f2eb2ba48fd036fb38a1840c1c1f58
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/repository/storage/ValueSetsStorageTest.kt
@@ -0,0 +1,95 @@
+package de.rki.coronawarnapp.vaccination.core.repository.storage
+
+import android.content.Context
+import de.rki.coronawarnapp.util.serialization.SerializationModule
+import io.kotest.matchers.shouldBe
+import io.mockk.MockKAnnotations
+import io.mockk.every
+import io.mockk.impl.annotations.MockK
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.test.runBlockingTest
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import testhelpers.BaseTest
+import testhelpers.preferences.MockSharedPreferences
+import java.util.Locale
+
+class ValueSetsStorageTest : BaseTest() {
+
+    @MockK lateinit var context: Context
+    lateinit var prefs: MockSharedPreferences
+
+    private val gson = SerializationModule().baseGson()
+
+    private val storedValueSetDE = ValueSetsStorage.StoredVaccinationValueSet(
+        languageCode = Locale.GERMAN,
+        vp = createValueSet(key = "1119305005", displayText = "Impfstoff-Name"),
+        mp = createValueSet(key = "EU/1/21/1529", displayText = "Arzneimittel-Name"),
+        ma = createValueSet(key = "ORG-100001699", displayText = "Hersteller-Name")
+    )
+
+    private val storedValueSetEN = ValueSetsStorage.StoredVaccinationValueSet(
+        languageCode = Locale.ENGLISH,
+        vp = createValueSet(key = "1119305005", displayText = "Vaccine-Name"),
+        mp = createValueSet(key = "EU/1/21/1529", displayText = "MedicalProduct-Name"),
+        ma = createValueSet(key = "ORG-100001699", displayText = "Manufactorer-Name")
+    )
+
+    private fun createValueSet(key: String, displayText: String): ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet {
+        val item = ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet.StoredItem(
+            key = key,
+            displayText = displayText
+        )
+        return ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet(items = listOf(item))
+    }
+
+    @BeforeEach
+    fun setup() {
+        MockKAnnotations.init(this)
+        prefs = MockSharedPreferences()
+        every { context.getSharedPreferences("valuesets_localdata", Context.MODE_PRIVATE) } returns prefs
+    }
+
+    private fun createInstance() = ValueSetsStorage(
+        context = context,
+        gson = gson
+    )
+
+    @Test
+    fun `Default value is empty value set`() {
+        createInstance().valueSet.value.run {
+            languageCode shouldBe Locale.ENGLISH
+            vp.items shouldBe emptyList()
+            mp.items shouldBe emptyList()
+            ma.items shouldBe emptyList()
+        }
+    }
+
+    @Test
+    fun `Clear resets value set`() {
+        createInstance().run {
+            valueSet.update { storedValueSetDE }
+            clear()
+
+            valueSet.value.also {
+                it.languageCode shouldBe Locale.ENGLISH
+                it.vp.items shouldBe emptyList()
+                it.mp.items shouldBe emptyList()
+                it.ma.items shouldBe emptyList()
+            }
+        }
+    }
+
+    @Test
+    fun `Updates values`() = runBlockingTest {
+        createInstance().valueSet.run {
+            update { storedValueSetDE }
+            value shouldBe storedValueSetDE
+            flow.first() shouldBe storedValueSetDE
+
+            update { storedValueSetEN }
+            value shouldBe storedValueSetEN
+            flow.first() shouldBe storedValueSetEN
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/testDeviceForTesters/java/de/rki/coronawarnapp/test/debugoptions/ui/DebugOptionsFragmentViewModelTest.kt b/Corona-Warn-App/src/testDeviceForTesters/java/de/rki/coronawarnapp/test/debugoptions/ui/DebugOptionsFragmentViewModelTest.kt
index 27b4fe9757b14077fea0e63b813f732064aeab88..c1b802516a2f5aa590dd3cf5ba6fcbd6d23e5906 100644
--- a/Corona-Warn-App/src/testDeviceForTesters/java/de/rki/coronawarnapp/test/debugoptions/ui/DebugOptionsFragmentViewModelTest.kt
+++ b/Corona-Warn-App/src/testDeviceForTesters/java/de/rki/coronawarnapp/test/debugoptions/ui/DebugOptionsFragmentViewModelTest.kt
@@ -31,7 +31,6 @@ class DebugOptionsFragmentViewModelTest : BaseTestInstrumentation() {
         every { environmentSetup.verificationCdnUrl } returns "verificationUrl"
         every { environmentSetup.dataDonationCdnUrl } returns "dataDonationUrl"
         every { environmentSetup.logUploadServerUrl } returns "logUploadServerUrl"
-        every { environmentSetup.vaccinationCdnUrl } returns "vaccinationCdnUrl"
         every { environmentSetup.crowdNotifierPublicKey } returns "crowdNotifierPublicKey"
         every { environmentSetup.appConfigPublicKey } returns "appConfigPublicKey"
 
diff --git a/prod_environments.json b/prod_environments.json
index 8c50a11f3fd336642c98f2cdbc19deb6c17aac4c..09d9015c150489eb2dac757a9dfbe5d25f476926 100644
--- a/prod_environments.json
+++ b/prod_environments.json
@@ -6,8 +6,6 @@
     "VERIFICATION_CDN_URL": "https://verification.coronawarn.app",
     "DATA_DONATION_CDN_URL": "https://data.coronawarn.app",
     "LOG_UPLOAD_SERVER_URL": "https://logupload.coronawarn.app",
-    "VACCINATION_PROOF_SERVER_URL": "https://api.recertify.ubirch.com",
-    "VACCINATION_CDN_URL": "https://placeholder",
     "SAFETYNET_API_KEY": "placeholder",
     "PUB_KEYS_SIGNATURE_VERIFICATION": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEc7DEstcUIRcyk35OYDJ95/hTg3UVhsaDXKT0zK7NhHPXoyzipEnOp3GyNXDVpaPi3cAfQmxeuFMZAIX2+6A5Xg==",
     "CROWD_NOTIFIER_PUBLIC_KEY": "gwLMzE153tQwAOf2MZoUXXfzWTdlSpfS99iZffmcmxOG9njSK4RTimFOFwDh6t0Tyw8XR01ugDYjtuKwjjuK49Oh83FWct6XpefPi9Skjxvvz53i9gaMmUEc96pbtoaA"