This issue has shown that, when we introduce new providers and propagate the configs to users, then remove the config ("asf" was removed and renamed to "default"), user configuration breaks
- #6358

One way of dealing with this is checking at startup time whether the configured providers are available, and if not, log a warning and fall back to the default provider.
super().__init__()
        self._services = {}
        self._mutex = threading.RLock()
    def get_service_container(self, name: str) -> Optional[ServiceContainer]:
        return self._services.get(name)
    def get_service(self, name: str) -> Optional[Service]:
        container = self.get_service_container(name)
        return container.service if container else None
    def add_service(self, service: Service) -> bool:
        state = ServiceState.AVAILABLE if service.is_enabled() else ServiceState.DISABLED
        self._services[service.name()] = ServiceContainer(service, state)
        return True
    def list_available(self) -> List[str]:
        return list(self._services.keys())
    def exists(self, name: str) -> bool:
        return name in self._services
    def is_running(self, name: str) -> bool:
        return self.get_state(name) == ServiceState.RUNNING
    def check(self, name: str) -> bool:
        if self.get_state(name) in [ServiceState.RUNNING, ServiceState.ERROR]:
            return self.get_service_container(name).check()
    def check_all(self):
        return any(self.check(service_name) for service_name in self.list_available())
    def get_state(self, name: str) -> Optional[ServiceState]: