A possible solution for the infinite loop would be something like:

```
def configureExecutor(): ExecutorServiceConfigurator = {
  def configurator(executor: String): ExecutorServiceConfigurator = executor match {
    case null | "" | "fork-join-executor" => new ForkJoinExecutorConfigurator(config.getConfig("fork-join-executor"), prerequisites)
    case "thread-pool-executor"          => new ThreadPoolExecutorConfigurator(config.getConfig("thread-pool-executor"), prerequisites)
    case fqcn => //...
  }
  
  config.getString("executor") match {
    case "default-executor" => new DefaultExecutorServiceConfigurator(config.getConfig("default-executor"), prerequisites, configurator(config.getString("default-executor.fallback")))
    case other => configurator(other)
  }
}
```

This way the "default-executor" is only a valid option for "executor", but not for "fallback".