KXftConfig::parseConfigFile is called for each config it can find. That is including global files. The function loads the config into m_doc. When no local file is present m_doc will contain the data of whatever was the last **global** config it had read. If anything now ends up triggering KXftConfig::apply() we'll be writing the global config to the user's fonts.conf. Spoiler alert.... as of Monday's master apply() is called the first time you run the kcm. Yay! This a) can actually break the entire configuration because the user config is included at rank 50, which will apply it before the last config (99.99% of the time > 50) and the last config may be written with that expectation (e.g. force-overriding certain aspects) a) if the last global config was the user include config the loading is now causing an infinite loop The easy fix I guess is clearing m_doc at some point. It does feel wonky dory to mutate the kxftconfig this way in general though. If I was to re-design this there'd be a Loader class which loads all configs and only once it has assembled the current state will it construct an kxftconfig object.