If you've ever fired up a fresh Spring Boot application, hit localhost:8080, and stared at that default green leaf icon in your browser tab — you know exactly what I'm talking about. That little leaf is a badge of honor for Java developers, but your users expect to see your actual brand logo.

Look at how companies like Stripe or GitHub handle their web apps. They don't leave default framework icons in their production builds. They serve crisp, optimized icons that build instant trust before the page even finishes rendering. A missing or default icon screams "unfinished side project."

Many older tutorials tell you to just drop an ICO file into your static folder and call it a day. I strongly advise against stopping there. We are building web apps in 2026, which means you need a modern stack that handles high-DPI displays and dark mode, while also playing nicely with Spring's strict routing rules.

The Quick Fix: The Static Folder Method

Spring Boot has built-in magic for static resources. By default, it looks for a file named favicon.ico in specific classpath directories and automatically serves it at the root URL (/favicon.ico).

Step 1: Prepare Your Icon File

First, you need a valid ICO file. Don't just rename a PNG to ICO (browsers hate that). Use Mzu favicondl to generate a proper multi-resolution ICO file from your logo.

Step 2: Place It in the Correct Directory

Drop your newly generated favicon.ico into one of the following directories in your Spring Boot project:

Restart your application. If you hit your root URL, the green leaf should be gone, replaced by your custom icon.

The Modern Approach: Thymeleaf and HTML Tags

Relying solely on the implicit root favicon.ico request is a legacy habit. Browsers will request it, but it gives you zero control over Apple Touch Icons or modern SVG formats.

You should explicitly declare your icons in your HTML templates. If you are using Thymeleaf (the standard templating engine for Spring), you can create a reusable <head> fragment.

<!-- In your fragments/head.html -->
<link rel='icon' type='image/svg+xml' href='/icons/favicon.svg'>
<link rel='icon' type='image/png' href='/icons/favicon-96x96.png' sizes='96x96'>
<link rel='apple-touch-icon' href='/icons/apple-touch-icon.png'>

Place these files inside src/main/resources/static/icons/. This explicitly tells the browser exactly what to load, bypassing the fallback root request entirely. If you need a refresher on the exact tags to use, check out our HTML guide for adding favicons.

The Gotcha: Spring Security Blocking Your Icon

This is where 90% of Java developers get stuck. You put the file in the right folder, you added the HTML tags, but the browser tab is completely blank. You open your DevTools network tab and see a 404 Not Found or a 302 Redirect to a login page.

If you have Spring Security on your classpath, it secures all endpoints by default — including static resources. When the browser tries to fetch /favicon.ico, Spring Security intercepts the unauthenticated request and blocks it.

How to Fix the Security Filter Chain

You need to explicitly tell Spring Security to ignore requests for your favicon and static icon directories. Open your security configuration class and update your SecurityFilterChain bean:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests(auth -> auth
            .requestMatchers('/favicon.ico', '/icons/**').permitAll()
            .anyRequest().authenticated()
        )
        .formLogin(Customizer.withDefaults());
    return http.build();
}

By adding requestMatchers('/favicon.ico', '/icons/**').permitAll(), you allow browsers to fetch your branding before the user logs in. This is critical for the login page itself to look professional.

Common Pitfalls to Avoid

Even with the perfect Spring configuration, things can still look broken. Here is what usually goes wrong:

Customizing your Spring Boot favicon takes a bit more effort than a static HTML site due to the routing and security layers. But getting rid of that default leaf is the first step in turning a local Java project into a production-ready web application.