This error means Spring Boot’s DispatcherServlet tried to find a handler for your incoming request, couldn’t find one, and then failed to find a default "no handler found" message template to send back.
The most common reason is that your request is hitting the wrong URL. This could be a typo, an incorrect HTTP method, or a path that simply doesn’t exist in your application’s routing.
Diagnosis: Use curl to test your endpoint directly and inspect the exact URL and method.
curl -v -X GET http://localhost:8080/your/expected/path
Look for HTTP/1.1 404 in the output. If the URL is correct, proceed to the next checks.
Another frequent cause is a misconfiguration of your web framework’s request mapping. For example, if you’re using Spring MVC, your @Controller or @RestController classes might not be scanned or your @RequestMapping annotations might be incorrect.
Diagnosis: Check your Application class. Ensure it has @SpringBootApplication (which includes @ComponentScan) and that your controller packages are within its scope.
@SpringBootApplication
@ComponentScan(basePackages = {"com.example.yourpackage"}) // Ensure this covers your controllers
public class YourApplication {
public static void main(String[] args) {
SpringApplication.run(YourApplication.class, args);
}
}
Fix: Verify the basePackages in @ComponentScan correctly includes the package where your controller classes reside. This ensures Spring finds and registers your request mappings.
If you’re using Spring Security, it might be intercepting the request before Spring MVC can even attempt to find a handler, leading to a 404 if the security configuration doesn’t permit access to that path.
Diagnosis: Temporarily disable Spring Security or loosen its rules for the affected path to see if the 404 disappears.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public/**").permitAll() // Example: allow access to /public
.anyRequest().authenticated()
.and()
.formLogin();
}
}
Fix: Adjust your HttpSecurity configuration to explicitly allow access to the missing endpoint or ensure the authentication flow correctly routes to your controllers after successful authentication.
A missing or incorrectly configured WebMvcConfigurer can also cause issues, especially if you’re doing custom path matching or view resolution.
Diagnosis: Review any custom WebMvcConfigurer implementations.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// If you're using this, ensure it's not overriding a path your controller handles
// registry.addViewController("/").setViewName("index");
}
// Other WebMvcConfigurer methods...
}
Fix: Ensure your WebMvcConfigurer doesn’t have conflicting mappings or is not inadvertently disabling essential request handling components.
If you’re deploying to a specific environment (like a WAR file in Tomcat), the context path might be different from what you expect, leading to requests not reaching your application’s root.
Diagnosis: Check your deployment descriptor (web.xml if applicable) or your application server’s configuration for the context path.
For embedded servers, check server.servlet.context-path in application.properties or application.yml.
server.servlet.context-path=/myapp
Fix: If the context path is set, prepend it to all your @RequestMapping paths or ensure your curl requests include it (e.g., http://localhost:8080/myapp/your/path).
Sometimes, the issue is as simple as the DispatcherServlet not being registered correctly, especially in non-Spring Boot setups or when migrating. In Spring Boot, this is usually automatic, but custom configurations can break it.
Diagnosis: Inspect your web.xml (if used) or your Java configuration for DispatcherServlet registration.
// Example if you were manually configuring DispatcherServlet (less common in Spring Boot)
@Configuration
public class ServletConfig {
@Bean
public ServletRegistrationBean dispatcherServlet() {
return new ServletRegistrationBean(new DispatcherServlet(), "/");
}
}
Fix: Ensure the DispatcherServlet is configured to handle all incoming requests (usually mapped to /).
Finally, if you’ve recently added or modified dependencies, a conflict or missing dependency related to web handling (like spring-webmvc or jackson-databind for JSON) could manifest as a routing issue.
Diagnosis: Run mvn dependency:tree or gradle dependencies to check for version conflicts or missing core web dependencies.
Fix: Resolve version conflicts, ensuring spring-webmvc and related libraries are present and compatible.
The next error you’ll likely see if you fix the 404 is a 500 Internal Server Error if your handler is found but throws an exception during execution, or a 405 Method Not Allowed if the path is found but the HTTP method is wrong.