I had a look at the method overloads for logger.error (and .warn) and there was only .error(msg, throwable), and .error(msg, Object[] args). So as soon as you pass a msg with params, any exception is just treated as another param for string substitution. I could be wrong of course!