Log4j2
conversion specifier
error handling
logging patterns
Java logging

Log4j2 - Unrecognized conversion specifier xwEx starting at position 160 in conversion pattern

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

This error means Log4j2 is parsing your PatternLayout string and found a conversion token it does not recognize. In most projects, that happens because the pattern contains a typo, the runtime Log4j2 version is older than the pattern expects, or the pattern was copied from a different logging framework.

What the Error Actually Means

PatternLayout strings use converters such as %d, %level, %logger, %msg, and %throwable. When Log4j2 sees %xwEx and the current parser does not know what that token means, startup fails or the logger falls back to a degraded configuration.

A good first step is replacing the unknown token with a known-safe baseline:

xml
<PatternLayout pattern="%d{ISO8601} [%t] %-5level %logger - %msg%n%throwable"/>

If that loads cleanly, the problem is not the logging system as a whole. It is the unsupported piece in the original pattern.

Use Supported Throwable Converters

If your goal is to render exceptions and stack traces, use converters that are broadly supported by Log4j2, such as %throwable, %ex, or %xEx, depending on the version and the formatting detail you want.

Example in log4j2.xml:

xml
1<?xml version="1.0" encoding="UTF-8"?>
2<Configuration status="WARN">
3  <Appenders>
4    <Console name="Console" target="SYSTEM_OUT">
5      <PatternLayout pattern="%d{ISO8601} [%t] %-5level %logger - %msg%n%ex{full}"/>
6    </Console>
7  </Appenders>
8
9  <Loggers>
10    <Root level="info">
11      <AppenderRef ref="Console"/>
12    </Root>
13  </Loggers>
14</Configuration>

Equivalent properties-based configuration:

properties
1appender.console.type = Console
2appender.console.name = Console
3appender.console.layout.type = PatternLayout
4appender.console.layout.pattern = %d{ISO8601} [%t] %-5level %logger - %msg%n%throwable
5
6rootLogger.level = info
7rootLogger.appenderRefs = console
8rootLogger.appenderRef.console.ref = Console

If %xwEx came from an online snippet or old shared config, replacing it with %throwable or %ex{full} is the fastest test.

Check the Runtime Version, Not Only the Build File

One subtle failure mode is a runtime version mismatch. Your pom.xml or Gradle file may declare one Log4j2 version, while the actual runtime loads another through an app server, shading, or transitive dependency conflict.

At runtime, print the implementation version:

java
1import org.apache.logging.log4j.LogManager;
2
3public class Log4jVersionCheck {
4    public static void main(String[] args) {
5        Package pkg = LogManager.class.getPackage();
6        System.out.println("Log4j2 version: " + pkg.getImplementationVersion());
7    }
8}

If the running version is older than the config example you copied, either simplify the pattern or upgrade the Log4j2 modules together so the API and Core jars stay aligned.

Reduce the Pattern Until It Parses

Long patterns make debugging harder because the parser error points at a character position, not at the design intent. The fastest troubleshooting method is to reduce the pattern to something minimal and then add pieces back one by one.

Start here:

text
%d [%t] %-5level %logger - %msg%n

Then add throwable output:

text
%d [%t] %-5level %logger - %msg%n%throwable

Then reintroduce advanced converters one at a time. That isolates the exact token causing the problem instead of forcing you to guess from a long format string.

This is especially useful when configuration comes from environment variables, properties files, or shared templates rather than one handwritten XML file.

Watch for Framework Mix-Ups

Another common cause is framework crossover. Logback, Log4j2, and other Java logging systems look similar on the surface, but their pattern converters are not interchangeable.

For example:

  • A Spring Boot app may default to Logback unless explicitly switched.
  • A shared config template may be written for a different logger backend.
  • A vendor starter may bring its own logging bridge and version constraints.

Verify which backend is really active before changing pattern syntax. If the application is running Logback and you are editing a Log4j2 pattern file, you are solving the wrong problem.

Keep Patterns Readable and Maintainable

Dense one-line patterns become fragile quickly. A layout should be simple enough that a teammate can change it without reopening old release notes to remember which converter is version-specific.

Practical approach:

  • Keep baseline format small.
  • Add exception rendering explicitly.
  • Store custom patterns in one shared config file.
  • Test logging startup in CI, not only in local IDE runs.

If you need advanced formatting, add one converter at a time and leave a short note in the config explaining why it is there.

Common Pitfalls

  • Copying %xwEx from blog posts without checking installed Log4j2 version.
  • Mixing Log4j2 pattern syntax with Logback configuration.
  • Assuming dependency management guarantees runtime logging version.
  • Debugging application code before validating logger configuration in isolation.
  • Keeping one huge pattern string that nobody can safely modify.

Summary

  • The error means your PatternLayout contains a converter the current Log4j2 runtime does not support.
  • Replace unknown tokens with supported specifiers such as %throwable or %ex{full} first.
  • Verify the actual runtime Log4j2 version, not only the declared dependency.
  • Debug long patterns by reducing them to a known-good baseline and adding tokens incrementally.
  • Make sure the application is truly using Log4j2 before applying Log4j2-specific fixes.

Course illustration
Course illustration

All Rights Reserved.