H2 Database
Error 90146
Database Initialization
Database Startup Issues
Troubleshooting

H2 Database not found error 90146. H2 database is not created on start

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

H2 error 90146, usually shown as "Database not found", means your application tried to open a database that H2 was told must already exist. In most cases the database is not created on startup because the JDBC URL, startup flags, or file path explicitly prevent automatic creation.

Why H2 Does Not Create the Database

H2 can run in memory or on disk. For file-based databases, the connection URL controls whether a missing database should be created automatically or whether the connection should fail.

A typical file URL looks like this:

properties
jdbc:h2:./data/appdb

If the database files are missing, H2 can create them when the connection opens.

But if your URL includes IFEXISTS=TRUE, H2 refuses to create a new database:

properties
jdbc:h2:./data/appdb;IFEXISTS=TRUE

That is one of the most common causes of error 90146.

A Working Example

Here is a minimal Java example that creates a file-based H2 database if it does not already exist:

java
1import java.sql.Connection;
2import java.sql.DriverManager;
3import java.sql.Statement;
4
5public class H2CreateDemo {
6    public static void main(String[] args) throws Exception {
7        String url = "jdbc:h2:./data/appdb";
8
9        try (Connection conn = DriverManager.getConnection(url, "sa", "");
10             Statement stmt = conn.createStatement()) {
11            stmt.execute("CREATE TABLE IF NOT EXISTS test(id INT PRIMARY KEY)");
12            System.out.println("Connected successfully");
13        }
14    }
15}

If ./data/appdb.mv.db does not exist yet, H2 creates it.

Now compare that with a failing URL:

java
String url = "jdbc:h2:./data/appdb;IFEXISTS=TRUE";

If the file is missing, the connection throws the "database not found" error instead of creating anything.

Check the File Path Carefully

Many startup failures are really path problems. Relative paths are resolved against the current working directory of the Java process, not necessarily the project root you expect.

For example:

properties
jdbc:h2:./data/appdb

may create or look for the database in a different folder depending on:

  • your IDE run configuration
  • your test runner
  • your production process working directory

If you suspect a path issue, try an absolute path temporarily while debugging:

properties
jdbc:h2:/absolute/path/to/data/appdb

That removes ambiguity and helps confirm whether the error is caused by location rather than creation rules.

Memory Databases Behave Differently

If you use an in-memory H2 database, creation happens automatically when the first connection opens:

properties
jdbc:h2:mem:testdb

In that case, error 90146 usually points to a different configuration mismatch, such as using the wrong URL name or expecting the same in-memory database across separate class loaders or processes.

Spring Boot Configuration Example

A Spring Boot application often configures H2 like this:

properties
1spring.datasource.url=jdbc:h2:./data/appdb
2spring.datasource.username=sa
3spring.datasource.password=
4spring.h2.console.enabled=true

If you accidentally add ;IFEXISTS=TRUE, startup can fail before schema initialization runs, because the database connection itself never succeeds.

Common Pitfalls

The biggest pitfall is adding IFEXISTS=TRUE without realizing what it does. That flag is useful when you want to ensure a database has already been provisioned, but it blocks auto-creation.

Another common issue is mixing up relative paths. An H2 URL that works in your IDE can fail in tests or inside a packaged application because the working directory changed.

A third problem is expecting schema creation tools to create the database file itself. Framework features such as schema.sql or JPA DDL generation run only after the database connection is established. They cannot help if H2 refuses to open the database in the first place.

Finally, developers sometimes confuse file-based and in-memory URLs. mem:testdb and ./data/testdb are completely different databases with different lifecycle behavior.

Summary

  • Error 90146 usually means H2 was asked to open an existing database that is not there.
  • 'IFEXISTS=TRUE is a common reason H2 does not create the database on startup.'
  • Check whether your JDBC URL is file-based or in-memory.
  • Verify the resolved file path, especially when using relative paths.
  • Fix the connection URL first; schema initialization runs only after a successful connection.

Course
Beginner
27 lessons
10 hours
System Design Fundamentals

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

View the course
System Design practice on Codemia

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

Practice system design