1. You are limited to N evaluation/reduction steps.
2. The language doesn't include primitives like recursion or loops.
3. You can have recursion or loops, but the language makes you somehow prove that your program will terminate.
I think (1) would be fine, but I don't know any configuration languages that use this approach.
(2) is restrictive/annoying whenever you want to implement any logic in the config language library. Eg. a tool uses a homegrown data format BAML and you need to convert JSON to BAML in the config. Now either you have to write and manually call a preprocessor, or you need to use a patched version of the <config language evaluator> that will have JSON->BAML as a built-in, or you must implement JSON->BAML without loops or recursion. For a more realistic example, imagine that a certain config string has to be HTML-escaped and the config language doesn't provide a built-in for that purpose.
(3) -- you don't want it. There are languages (like Agda) that let you prove things like "this program terminates", but writing those proofs can be harder than writing the program itself.