Fix: Spring Boot Whitelabel Error Page - This application has no explicit mapping
Quick Answer
How to fix the Spring Boot Whitelabel Error Page caused by missing controller mappings, wrong component scan, wrong package structure, and missing Thymeleaf templates.
The Error
You open your Spring Boot app in the browser and see:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
There was an unexpected error (type=Not Found, status=404).Or variations:
There was an unexpected error (type=Internal Server Error, status=500).There was an unexpected error (type=Method Not Allowed, status=405).Spring Boot could not find a controller method to handle the requested URL. Instead of a raw HTTP error, it shows the Whitelabel Error Page as a fallback.
Why This Happens
Spring Boot maps HTTP requests to @Controller or @RestController methods using @RequestMapping, @GetMapping, @PostMapping, etc. When no mapping matches the requested URL, Spring returns a 404 and shows the whitelabel page.
Common causes:
- Missing or wrong
@RequestMapping. The URL you are accessing does not match any controller endpoint. - Controller not scanned. The controller class is not in a package that Spring Boot scans.
- Wrong HTTP method. You send a GET request but the controller only handles POST.
- Missing
@RestControlleror@Controller. The class is not annotated as a controller. - Application class in the wrong package. The
@SpringBootApplicationclass must be in a root package that encompasses all controllers. - Thymeleaf template not found. A
@Controllermethod returns a view name but the template does not exist.
Fix 1: Add a Controller with the Right Mapping
The most common fix. Create a controller that handles the URL you are accessing:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HomeController {
@GetMapping("/")
public String home() {
return "Hello, World!";
}
@GetMapping("/api/status")
public Map<String, String> status() {
return Map.of("status", "running");
}
}Key annotations:
@RestController— for REST APIs (returns JSON/text directly)@Controller— for server-rendered views (returns template names)@GetMapping("/path")— handles GET requests to/path@PostMapping("/path")— handles POST requests to/path
Check that the URL matches:
@GetMapping("/api/users") // Accessible at http://localhost:8080/api/users
public List<User> getUsers() { ... }If you access http://localhost:8080/users (missing /api), you get the whitelabel page.
Fix 2: Fix the Package Structure
Spring Boot’s @SpringBootApplication enables component scanning starting from the package the main class is in. If your controllers are in a package outside this scan range, they are invisible to Spring.
Broken structure:
com.example.app.MyApplication.java ← @SpringBootApplication
com.other.controllers.UserController.java ← NOT scanned!Fixed — controllers in a sub-package:
com.example.app.MyApplication.java
com.example.app.controller.UserController.java ← Scanned ✓
com.example.app.service.UserService.java ← Scanned ✓The @SpringBootApplication class at com.example.app scans com.example.app and all sub-packages.
Fix — explicitly specify scan packages:
@SpringBootApplication(scanBasePackages = {"com.example.app", "com.other.controllers"})
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}Pro Tip: Always put your
@SpringBootApplicationclass in the root package of your project. Every controller, service, and repository should be in a sub-package. This is the standard convention and avoids scanning issues.
Fix 3: Check @Controller vs @RestController
Using @Controller without Thymeleaf or a view resolver causes a different problem — Spring looks for a template file instead of returning the string:
Broken:
@Controller
public class HomeController {
@GetMapping("/")
public String home() {
return "Hello, World!"; // Spring looks for a template named "Hello, World!"
}
}Fixed — use @RestController for API responses:
@RestController
public class HomeController {
@GetMapping("/")
public String home() {
return "Hello, World!"; // Returns the string directly
}
}Or use @ResponseBody with @Controller:
@Controller
public class HomeController {
@GetMapping("/")
@ResponseBody
public String home() {
return "Hello, World!";
}
}For template-based responses, create the template:
If you want @Controller to render HTML templates, add Thymeleaf and create the template:
@Controller
public class HomeController {
@GetMapping("/")
public String home(Model model) {
model.addAttribute("message", "Hello!");
return "home"; // Looks for src/main/resources/templates/home.html
}
}Create src/main/resources/templates/home.html:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<h1 th:text="${message}">Placeholder</h1>
</body>
</html>Fix 4: Fix the HTTP Method
A 405 whitelabel error means the URL exists but not for the HTTP method you used:
@PostMapping("/api/users")
public User createUser(@RequestBody User user) { ... }Accessing GET http://localhost:8080/api/users in the browser returns 405 because only POST is mapped.
Fix: Add the correct mapping:
@GetMapping("/api/users")
public List<User> getUsers() { ... }
@PostMapping("/api/users")
public User createUser(@RequestBody User user) { ... }Or use @RequestMapping for multiple methods:
@RequestMapping(value = "/api/users", method = {RequestMethod.GET, RequestMethod.POST})
public ResponseEntity<?> handleUsers(HttpServletRequest request) { ... }Fix 5: Check Server Port and Context Path
You might be accessing the wrong URL:
Check the port:
# application.properties
server.port=8081If the port is 8081, access http://localhost:8081/, not http://localhost:8080/.
Check the context path:
# application.properties
server.servlet.context-path=/api/v1With this setting, all URLs are prefixed: http://localhost:8080/api/v1/users instead of http://localhost:8080/users.
Check for a reverse proxy prefix:
Behind Nginx or a load balancer, the path might be different. Check your proxy configuration.
Fix 6: Debug Registered Mappings
See exactly which URLs Spring Boot has registered:
Enable Actuator:
Add to pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>In application.properties:
management.endpoints.web.exposure.include=mappingsAccess http://localhost:8080/actuator/mappings to see all registered URL mappings.
Or add debug logging:
logging.level.org.springframework.web=DEBUGSpring logs every registered mapping at startup:
Mapped "{[/api/users],methods=[GET]}" onto public java.util.List<User> UserController.getUsers()If your controller is not listed, it is not being scanned (see Fix 2).
Common Mistake: Adding a controller class but forgetting to annotate it with
@RestControlleror@Controller. Without the annotation, Spring does not register it as a request handler. Check that the annotation is present and imported fromorg.springframework.web.bind.annotation.
Fix 7: Customize the Error Page
If you want to replace the whitelabel page with a custom error page:
Disable the whitelabel page:
server.error.whitelabel.enabled=falseAdd a custom error controller:
@Controller
public class CustomErrorController implements ErrorController {
@RequestMapping("/error")
public String handleError(HttpServletRequest request) {
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
if (status != null) {
int statusCode = Integer.parseInt(status.toString());
if (statusCode == 404) {
return "error-404";
}
}
return "error";
}
}Add static error pages:
Place HTML files in src/main/resources/static/error/:
404.html— displayed for 404 errors500.html— displayed for 500 errors4xx.html— catch-all for 4xx errors5xx.html— catch-all for 5xx errors
Spring Boot automatically serves these based on the error status code.
Fix 8: Fix Spring Security Blocking
Spring Security might block access to your controller before it is even reached:
There was an unexpected error (type=Forbidden, status=403).Fix: Configure security to permit your endpoints:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/", "/api/public/**").permitAll()
.anyRequest().authenticated()
);
return http.build();
}
}For development, permit all (not for production):
http.authorizeHttpRequests(auth -> auth.anyRequest().permitAll());If authentication itself fails, the issue might be similar to Fix: AWS AccessDeniedException where permissions need to be correctly configured.
Still Not Working?
If the whitelabel error persists:
Check for classpath issues. Run mvn dependency:tree or gradle dependencies to verify all Spring Boot dependencies are present. A missing spring-boot-starter-web dependency means no embedded server.
Check for port conflicts. If port 8080 is already in use, Spring Boot might fail to start or start on a different port. See Fix: Port 3000 already in use for resolving port conflicts.
Check for profile-specific configuration. A different application-{profile}.properties might override your settings:
java -jar app.jar --spring.profiles.active=prodCheck the build output. If using Maven, ensure the project builds without errors:
mvn clean packageFor Maven dependency resolution failures, see Fix: Maven could not resolve dependencies.
Check for circular dependencies. Spring might fail to create beans if there are circular dependencies. The error message in the console will mention BeanCurrentlyInCreationException.
Enable full stack trace logging:
server.error.include-stacktrace=always
server.error.include-message=alwaysThis shows the full error details on the whitelabel page, making debugging easier.
If the Gradle build itself fails before you can run the application, see Fix: Gradle build failed.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: Spring BeanCreationException: Error creating bean with name
How to fix Spring BeanCreationException error creating bean caused by missing dependencies, circular references, wrong annotations, configuration errors, and constructor issues.
Fix: Spring Boot Web server failed to start. Port 8080 was already in use
How to fix the Spring Boot error 'Web server failed to start. Port 8080 was already in use' by killing blocking processes, changing ports, fixing IDE issues, and resolving Docker conflicts.
Fix: Java ClassCastException: class X cannot be cast to class Y
How to fix Java ClassCastException by using instanceof checks, fixing generic type erasure, resolving ClassLoader conflicts, correcting raw types, and using pattern matching in Java 16+.
Fix: Java ConcurrentModificationException
How to fix Java ConcurrentModificationException caused by modifying a collection while iterating, HashMap concurrent access, stream operations, and multi-threaded collection usage.