Spring Boot
h2-console
403 error
Spring Security
troubleshooting

Spring Boot /h2-console throws 403 with Spring Security 1.5.2

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

If /h2-console returns 403 Forbidden in Spring Boot 1.5.2, the problem is usually not H2 itself. Spring Security is blocking the console because the endpoint is protected, the console uses frames, and POST actions inside the console can also trigger CSRF protection.

Why the H2 Console Fails

The H2 web console is a development tool exposed over HTTP. In a Spring Boot application with Spring Security enabled, three things commonly block it:

  • The path is not explicitly permitted
  • CSRF protection rejects the console's form submissions
  • Frame headers prevent the UI from rendering

So fixing the issue usually means changing security rules in all three areas, not only adding one permitAll() matcher.

Security Configuration for Spring Boot 1.5.2

In this version line, the common setup uses WebSecurityConfigurerAdapter. A minimal development-only configuration looks like this:

java
1import org.springframework.context.annotation.Configuration;
2import org.springframework.security.config.annotation.web.builders.HttpSecurity;
3import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
4import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
5
6@Configuration
7@EnableWebSecurity
8public class SecurityConfig extends WebSecurityConfigurerAdapter {
9
10    @Override
11    protected void configure(HttpSecurity http) throws Exception {
12        http
13            .authorizeRequests()
14                .antMatchers("/h2-console/**").permitAll()
15                .anyRequest().authenticated()
16            .and()
17            .csrf()
18                .ignoringAntMatchers("/h2-console/**")
19            .and()
20            .headers()
21                .frameOptions().sameOrigin();
22    }
23}

Each line matters:

  • 'permitAll() lets the request reach the console'
  • 'ignoringAntMatchers() prevents CSRF from blocking login and query actions inside the console'
  • 'frameOptions().sameOrigin() allows the framed UI to render'

Make Sure the Console Is Enabled

The security fix only helps if H2 console support is enabled in the application configuration:

properties
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

If the path in configuration differs from the path in your security matcher, you will still get blocked.

Keep the Fix Limited to Development

Opening the H2 console broadly is convenient for local work, but it should not be treated like a production feature. A safer pattern is to enable it only for a development profile:

java
1import org.springframework.context.annotation.Profile;
2
3@Profile("dev")
4@Configuration
5@EnableWebSecurity
6public class DevSecurityConfig extends WebSecurityConfigurerAdapter {
7    @Override
8    protected void configure(HttpSecurity http) throws Exception {
9        http
10            .authorizeRequests()
11                .antMatchers("/h2-console/**").permitAll()
12                .anyRequest().authenticated()
13            .and()
14            .csrf()
15                .ignoringAntMatchers("/h2-console/**")
16            .and()
17            .headers()
18                .frameOptions().sameOrigin();
19    }
20}

That keeps the console accessible for local debugging without quietly weakening every environment.

Why 403 Happens Even After permitAll()

This is the part that confuses many developers. They add a matcher and still see a broken console. That usually means the request is now authorized, but the console's form posts are still rejected by CSRF, or the browser refuses to render the frame because of the default security headers.

So if permitAll() alone does not solve it, that is expected. The H2 console is unusual because it depends on both relaxed path rules and relaxed frame handling.

Another easy check is the browser network panel. If the initial GET succeeds but a later POST fails with 403, you are dealing with CSRF. If the page loads but the frame is blocked, the response headers are the next place to inspect.

Common Pitfalls

  • Permitting /h2-console/** but forgetting to ignore CSRF for the same path.
  • Disabling CSRF globally when only the console needs an exception.
  • Forgetting frameOptions().sameOrigin(), which leaves the console blank or blocked in the browser.
  • Using a custom H2 path in properties and a different path in the security matcher.

Summary

  • A 403 on /h2-console in Spring Boot 1.5.2 is usually caused by Spring Security, not by H2.
  • You need to permit the path, relax CSRF for that path, and allow same-origin frames.
  • 'WebSecurityConfigurerAdapter is the normal place to apply the fix in this version line.'
  • Keep H2 console access limited to development environments.
  • If permitAll() alone does not help, check CSRF and frame headers next.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.