> Markdown version of [Custom Error Views](https://vaadin.com/docs/next/flow/security/spring/error-views). Section index: [llms.txt](https://vaadin.com/docs/next/flow/llms.txt)

# Custom Error Views

[Access-Denied & Not-Found Views](https://vaadin.com/docs/next/flow/security/access-control/error-views.md) describes how to create custom error views for routes that don’t exist or that the user can’t access. With Spring Security, a custom not-found view also needs additional security configuration to be reachable for users.

## <a id="custom-not-found-view"></a>Custom Not-Found View

In an application secured with `VaadinSecurityConfigurer`, the not-found view also needs a relaxed catch-all request rule, so that requests for non-existing pages reach the Vaadin servlet. By default, `VaadinSecurityConfigurer` denies every request that isn’t explicitly allowed. A URL that doesn’t match any route, entered in the browser’s address bar or opened from a bookmark, is therefore denied by Spring Security before Vaadin can show the not-found view. The access annotation on the view doesn’t change this, as it’s checked only after the request reaches the Vaadin servlet.

The security configuration then relaxes the catch-all rule with `anyRequest()`:

`SecurityConfiguration.java`

```java
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http.with(VaadinSecurityConfigurer.vaadin(), configurer -> {
        configurer.loginView(LoginView.class)
                .anyRequest(AuthorizedUrl::permitAll); // (1)
    });
    return http.build();
}
```

1. Lets requests that match no other rule reach the Vaadin servlet, which shows the not-found view for them.

This doesn’t expose your views: they’re still protected at the HTTP layer by the request matchers of `VaadinSecurityConfigurer`, and by navigation access control. However, the catch-all rule also covers every other endpoint of the application, such as REST controllers or Spring Boot Actuator endpoints. Protect those with rules of their own before relaxing the catch-all rule, as rules added to `http` before the configurer are applied first.

If only signed-in users need to see the not-found view, use `AuthorizedUrl::authenticated` instead of `AuthorizedUrl::permitAll`. Users who aren’t signed in are then sent to the log-in view for any unknown URL, and other unmatched endpoints require authentication. See [Security Configuration](https://vaadin.com/docs/next/flow/security/spring/security-configuration.md) for the other options of `anyRequest()`, and [Handle Errors](https://vaadin.com/docs/next/building-apps/ui-basics/handle-errors.md) for a guide to the error views of an application.
