Introduction
The Spring Boot startup banner -- the ASCII art displayed when the application starts -- can appear as garbled characters, boxes, or question marks when the console encoding does not match the banner file encoding. This is particularly common in Docker containers, CI/CD pipelines, and remote SSH sessions where the default character encoding is not UTF-8. While this is not a functional issue (the application starts correctly), garbled banners indicate a broader encoding misconfiguration that can affect logging, database connections, and file I/O.
Symptoms
Banner appears as garbled characters:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _ | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.2.3)
APPLICATION ΚΌ ```
Or with Unicode banners:
\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2510
\u2502 ??? \u2502 <-- Shows as boxes or question marks
\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2518Or the banner file is not found:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _ | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.2.3)
WARN: Banner file not found at classpath:banner.txt ```
Common Causes
- Console encoding not UTF-8: Docker containers often default to
ANSI_X3.4-1968orClocale - Banner file saved with wrong encoding:
banner.txtsaved as Windows-1252 instead of UTF-8 - JVM default encoding mismatch:
file.encodingsystem property does not match the console - SSH client encoding mismatch: Terminal emulator sends UTF-8 but SSH session is configured differently
- Font missing Unicode characters: The terminal font does not have glyphs for the banner's characters
- Banner contains BOM: UTF-8 BOM at the start of banner.txt causes rendering issues
Step-by-Step Fix
Step 1: Set JVM encoding to UTF-8
```bash # Docker container docker run -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 myapp
# Or in Dockerfile ENV LANG=C.UTF-8 ENV LC_ALL=C.UTF-8
# JVM argument java -Dfile.encoding=UTF-8 -jar myapp.jar
# Or in spring-boot-maven-plugin <configuration> <jvmArguments>-Dfile.encoding=UTF-8</jvmArguments> </configuration> ```
Step 2: Use ASCII-only banner for portability
Create src/main/resources/banner.txt with ASCII-only content:
| Spring Boot Application | |
|---|---|
| ----w |
:: Spring Boot :: ${spring-boot.version} ```
ASCII characters render correctly regardless of encoding.
Step 3: Disable banner in production
spring:
main:
banner-mode: off # Or "console" for development, "log" for loggingOr via JVM argument:
java -Dspring.main.banner-mode=off -jar myapp.jarStep 4: Use image banner with fallback
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplicationBuilder builder = new SpringApplicationBuilder(MyApplication.class);
builder.banner(new ImageBanner(
new ClassPathResource("banner.png"),
ImageBanner.OutputEncoding.ASCII // Force ASCII output
));
builder.run(args);
}
}Prevention
- Set
LANG=C.UTF-8andLC_ALL=C.UTF-8in all Dockerfiles - Use ASCII-only banners for maximum portability
- Disable banners in production (
banner-mode: off) to reduce startup noise - Set
-Dfile.encoding=UTF-8as a JVM argument in all deployment configurations - Add an integration test that verifies the banner prints without garbled characters
- Use
spring.main.banner-mode=logto write the banner to the application log instead of the console