Olson CloudWorks 🚀

Spring Boot not serving static content

September 19, 2026

Spring Boot not serving static content

Are you wrestling with the frustrating issue of Spring Boot not serving static content? You’re not alone. Many developers, from beginners to seasoned professionals, encounter this problem when building web applications with Spring Boot. Static content, such as CSS stylesheets, JavaScript files, images, and even HTML files, are the backbone of any modern web application’s user interface. When Spring Boot fails to deliver these assets correctly, the application’s front-end can appear broken, incomplete, or simply non-functional. Understanding the common causes and solutions for this issue is crucial for any Spring Boot developer aiming to create robust and user-friendly web applications. This article will guide you through the common pitfalls and provide practical solutions to ensure your static content is served correctly.

Understanding Why Spring Boot Might Not Serve Static Content

Several factors can contribute to Spring Boot’s inability to serve static content correctly. The most common culprit is incorrect configuration. Spring Boot, by default, looks for static resources in specific locations within the classpath and webapp directory. If your static files are not placed in these default locations or if the configuration is overridden incorrectly, Spring Boot will not be able to find and serve them. It is essential to verify the location of your static resources and ensure that it aligns with Spring Boot’s default behavior or your custom configuration. Another common issue is related to Maven or Gradle build configurations, which might exclude the static resources during the build process. Double-checking your build configuration to ensure these resources are included in the final artifact is vital.

Furthermore, security configurations can sometimes interfere with static content serving. Spring Security, for example, might block access to static resources if not configured correctly. You may need to explicitly allow access to static resources in your security configuration to ensure they are served without authentication. Incorrect caching configurations can also lead to problems. If static resources are cached aggressively, users might not see the latest versions of your CSS or JavaScript files after you have made changes. Properly configuring caching headers can help prevent this issue. As stated by Baeldung, “Spring Boot automatically serves static resources located in /static, /public, /resources, and /META-INF/resources directories in the classpath.” Baeldung’s Spring Boot Static Content Guide offers valuable insights into configuring static resources.

Incorrect file permissions on the server can also prevent Spring Boot from accessing and serving static content. Ensure that the user running the Spring Boot application has the necessary read permissions on the static resource files. Misconfigured URL mappings can also lead to problems. If your URL mappings conflict with the default static resource mappings, Spring Boot might not be able to resolve the correct resource. It is important to carefully review your URL mappings and ensure they do not overlap with the default static resource paths.

Common Configuration Issues and Solutions

One of the most frequent issues arises from placing static resources in the wrong directory. Spring Boot automatically serves content from specific directories. If you deviate from these defaults, you must explicitly configure the resource handling. These default locations include /static, /public, /resources, and /META-INF/resources within the classpath, and also from the root of the web application (if you are deploying as a WAR file). Placing your static files outside of these locations will result in Spring Boot being unable to find and serve them. Therefore, the simplest solution is often to ensure your CSS, JavaScript, and image files are within one of these directories.

Another common mistake is related to overriding the default resource handling configuration. If you have customized the WebMvcConfigurer in your Spring Boot application, you might have inadvertently disabled the default static resource handling. This can happen if you implement the addResourceHandlers method but fail to include the default resource locations. To fix this, ensure that your custom addResourceHandlers method includes the default resource locations along with any custom locations you have defined. Additionally, check your application.properties or application.yml file for any properties that might be overriding the default static resource locations. Properties like spring.resources.static-locations can be used to customize the resource locations, but if configured incorrectly, they can lead to issues. For example, a value like spring.resources.static-locations: classpath:/custom-static/ will tell Spring Boot to look in the /custom-static folder instead of the default locations.

The following properties should be reviewed in application.properties or application.yml:

  • spring.resources.static-locations: Defines the locations Spring Boot searches for static resources.
  • spring.mvc.static-path-pattern: Defines the URL pattern for serving static resources.
  • spring.resources.cache.cachecontrol.max-age: Configures the caching behavior of static resources.

Troubleshooting Steps for Static Content Delivery

When encountering issues with Spring Boot not serving static content, a systematic troubleshooting approach is essential. Start by verifying the location of your static resources. Ensure they are placed within one of the default locations or a custom location that you have correctly configured in your application.properties or application.yml file. Next, inspect your browser’s developer tools to identify the specific static resources that are failing to load. The “Network” tab will show you the HTTP status codes for each resource, which can provide valuable clues about the cause of the problem. A 404 error, for example, indicates that the resource was not found at the specified URL.

Check your Spring Boot application logs for any error messages related to static resource handling. These logs might contain information about missing resources, configuration errors, or security restrictions. Enable debug logging for Spring Web MVC to get more detailed information about how Spring Boot is handling static resource requests. You can achieve this by adding logging.level.org.springframework.web.servlet=DEBUG to your application.properties or application.yml file. This will provide verbose output that can help you pinpoint the source of the problem. Consider using a tool like Postman to manually test the static resource URLs. This can help you isolate whether the issue is with Spring Boot or with the front-end code that is requesting the resources. More helpful tips.

Here are the steps to verify your static content delivery:

  1. Verify the location of static resources.
  2. Inspect browser’s developer tools for HTTP status codes.
  3. Check Spring Boot application logs for error messages.
  4. Enable debug logging for Spring Web MVC.
  5. Test the static resource URLs using Postman.

Security Considerations and Caching Strategies

Security is a paramount concern when serving static content. Spring Security, by default, might restrict access to static resources, requiring explicit configuration to allow access. Ensure that your security configuration permits unauthenticated access to static resources. This typically involves configuring your WebSecurityConfigurerAdapter to exclude static resource paths from authentication requirements. A common approach is to use the antMatchers method to specify the paths to static resources and permit all access to them. For example, .antMatchers("/static/").permitAll() will allow unauthenticated access to all resources under the /static/ directory.

Caching is another critical aspect of static content delivery. Properly configured caching can significantly improve the performance of your web application by reducing the number of requests to the server. Spring Boot provides several ways to configure caching for static resources. You can use the spring.resources.cache.cachecontrol properties in your application.properties or application.yml file to set cache control headers for static resources. For example, spring.resources.cache.cachecontrol.max-age=3600 will set the max-age directive of the Cache-Control header to 3600 seconds (1 hour). You can also use the CacheControl class in your Spring MVC configuration to programmatically configure caching headers. It’s important to balance caching with the need to ensure users receive the latest versions of your static resources. Aggressive caching can lead to users seeing outdated content, so carefully consider the appropriate caching duration for your application. According to Google’s PageSpeed Insights, leveraging browser caching can significantly reduce page load times Learn more about browser caching.

Infographic here showing common Spring Boot static content errors and solutions
FAQ: Spring Boot Static Content Issues --------------------------------------
Why are my CSS styles not being applied in my Spring Boot application?
This often happens when the CSS file is not correctly placed in one of Spring Boot's default static resource directories (e.g., /static, /public). Also, double-check your HTML to ensure the CSS file is linked correctly with the right path. Caching can also be the culprit, so clear your browser cache or use a hard refresh.
How do I serve static content from a custom directory in Spring Boot?
You can customize the static resource locations by setting the spring.resources.static-locations property in your application.properties or application.yml file. For example, setting spring.resources.static-locations=classpath:/my-static/ will tell Spring Boot to serve static content from the /my-static/ directory within your classpath.
Why am I getting a 404 error when trying to access my static resources?
A 404 error typically indicates that the resource is not found at the specified URL. Verify that the file exists in the correct location, that the URL mapping is correct, and that there are no conflicting URL mappings that might be intercepting the request. Ensure that your build configuration includes the static resources in the final artifact. Additionally, check your security configuration to ensure that access to static resources is not being blocked.
**Spring Boot not serving static content** can be a stumbling block, but with a clear understanding of the potential causes and solutions, you can quickly resolve the issue and get your web application up and running smoothly. Remember to double-check your configuration, verify the location of your static resources, and pay attention to security and caching considerations. By following the troubleshooting steps outlined in this article, you can effectively diagnose and fix static content delivery problems. Spring's documentation is a great resource [Check out Spring Boot documentation](https://spring.io/projects/spring-boot).

If you’ve followed these steps and are still facing challenges, don’t hesitate to explore Spring Boot’s comprehensive documentation or seek assistance from the vibrant Spring Boot community. Remember that a well-structured and correctly configured application will provide a seamless experience for your users. Consider exploring related topics like Spring Security configuration, advanced caching strategies, and build tool optimization to further enhance your Spring Boot development skills. Now go forth and build amazing web applications!

Question & Answer :
I can’t get my Spring Boot project to serve static content.

I’ve placed a folder named static under src/main/resources. Inside it, I have a folder named images. When I package the app and run it, it can’t find the images I have put on that folder.

I’ve tried to put the static files in public, resources and META-INF/resources but nothing works.

If I jar -tvf app.jar I can see that the files are inside the jar in the right folder: /static/images/head.png for example, but calling: http://localhost:8080/images/head.png, all I get is a 404

Any idea why spring-boot is not finding this? (I’m using 1.1.4 BTW)

Not to raise the dead after more than a year, but all the previous answers miss some crucial points:

  1. @EnableWebMvc on your class will disable org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration. That’s fine if you want complete control but otherwise, it’s a problem.

  2. There’s no need to write any code to add another location for static resources in addition to what is already provided. Looking at org.springframework.boot.autoconfigure.web.ResourceProperties from v1.3.0.RELEASE, I see a field staticLocations that can be configured in the application.properties. Here’s a snippet from the source:

    /** * Locations of static resources. Defaults to classpath:[/META-INF/resources/, * /resources/, /static/, /public/] plus context:/ (the root of the servlet context). */ private String[] staticLocations = RESOURCE_LOCATIONS; 
    
  3. As mentioned before, the request URL will be resolved relative to these locations. Thus src/main/resources/static/index.html will be served when the request URL is /index.html. The class that is responsible for resolving the path, as of Spring 4.1, is org.springframework.web.servlet.resource.PathResourceResolver.

  4. Suffix pattern matching is enabled by default which means for a request URL /index.html, Spring is going to look for handlers corresponding to /index.html. This is an issue if the intention is to serve static content. To disable that, extend WebMvcConfigurerAdapter (but don’t use @EnableWebMvc) and override configurePathMatch as shown below:

    @Override public void configurePathMatch(PathMatchConfigurer configurer) { super.configurePathMatch(configurer); configurer.setUseSuffixPatternMatch(false); } 
    

IMHO, the only way to have fewer bugs in your code is not to write code whenever possible. Use what is already provided, even if that takes some research, the return is worth it.

Edit July 2021:

  1. WebMvcConfigurerAdapter has been deprecated since Spring 5. Implement WebMvcConfigurer and annotate with @Configuration.