I’ve run into a critical issue with my Metabase Docker setup and I’m hoping for guidance. Here’s the situation:
Setup:
Metabase running in Docker for ~6 months
Database: H2, stored in a Docker volume (metabase.db.mv.db)
All reports and dashboards have been working perfectly
Host OS rebooted recently
Problem:
After a host reboot, my Metabase container stopped working. Any attempt to start the container now fails immediately. Logs show the database file appears locked or inaccessible.
Examples of errors when starting the Docker container:
Caused by: org.h2.mvstore.MVStoreException: The file is locked: /metabase.db/metabase.db.mv.db
Caused by: java.nio.channels.OverlappingFileLockException
When trying to import the same H2 file into a new container or migrate it to PostgreSQL, I get:
Database may be already in use: "/metabase-data/metabase.db.mv.db"
Error while creating file "/metabase-data/metabase.db.mv.db (a file with this name already exists)"
What I’ve tried:
Stopping all containers and making sure no other process is using the H2 file
Starting a fresh Metabase container with the same volume
Restoring backups from 2–3 months ago
Attempting to migrate the H2 database to PostgreSQL
All attempts result in the same “file locked” or “database already in use” errors.
Additional info:
This is not a typical concurrent access issue — the database was working fine before the host reboot.
Even older backups fail to start, which suggests a possible corruption or H2 file lock metadata issue. What I find weird, is that the old backups back then did not have any file corruption, and now they seem to… as they do not work…
Request for help:
Is there a safe way to unlock or repair the H2 .mv.db file after a host reboot?
Can I recover my existing Metabase data without losing all dashboards/reports?
Is migration to PostgreSQL possible with the current state of the H2 file?
Any guidance or steps to safely recover the database would be greatly appreciated.
Hi, thank you for the reply .
I tried out these commands for recovering the corrupted db, but still getting the same errors… :
gpsadmin@webgis002:/datadrive/webapps/metabase_new/data/metabase.db$ java --add-opens java.base/java.nio=ALL-UNNAMED -cp metabase.jar org.h2.tools.RunScript -script metabase.db.h2.sql -url jdbc:h2:pwd/metabase.db
Exception in thread "main" org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "SEARCH_INDEX__AVEDEKRQ5C1CF0BLPENMR" not found; SQL statement:
CREATE PRIMARY KEY "PUBLIC"."PRIMARY_KEY_76" ON "PUBLIC"."SEARCH_INDEX__AVEDEKRQ5C1CF0BLPENMR"("ID") [42102-214]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:502)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
at org.h2.message.DbException.get(DbException.java:223)
at org.h2.message.DbException.get(DbException.java:199)
at org.h2.command.ddl.CreateIndex.update(CreateIndex.java:68)
at org.h2.engine.MetaRecord.prepareAndExecute(MetaRecord.java:77)
at org.h2.engine.Database.executeMeta(Database.java:660)
at org.h2.engine.Database.executeMeta(Database.java:634)
at org.h2.engine.Database.(Database.java:357)
at org.h2.engine.Engine.openSession(Engine.java:92)
at org.h2.engine.Engine.openSession(Engine.java:222)
at org.h2.engine.Engine.createSession(Engine.java:201)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
at org.h2.jdbc.JdbcConnection.(JdbcConnection.java:122)
at org.h2.util.JdbcUtils.getConnection(JdbcUtils.java:288)
at org.h2.util.JdbcUtils.getConnection(JdbcUtils.java:270)
at org.h2.tools.RunScript.process(RunScript.java:312)
at org.h2.tools.RunScript.runTool(RunScript.java:139)
at org.h2.tools.RunScript.main(RunScript.java:66)
gpsadmin@webgis002:/datadrive/webapps/metabase_new/data/metabase.db$ java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar migrate release-locks
2026-01-26 08:23:55,010 INFO metabase.util :: Maximum memory available to JVM: 7.8 GB
2026-01-26 08:23:58,062 INFO util.encryption :: Saved credentials encryption is DISABLED for this Metabase instance. �
For more information, see Redirecting…
2026-01-26 08:23:58,438 WARN app-db.env :: WARNING: Using Metabase with an H2 application database is not recommended for production deployments. For production deployments, we highly recommend using Postgres, MySQL, or MariaDB instead. If you decide to continue to use H2, please be sure to back up the database file regularly. For more information, see Redirecting…
2026-01-26 08:24:09,755 INFO driver.impl :: Registered abstract driver :sql �
2026-01-26 08:24:09,822 INFO driver.impl :: Registered abstract driver :sql-jdbc (parents: [:sql]) �
2026-01-26 08:24:09,853 INFO driver.impl :: Registered driver :h2 (parents: [:sql-jdbc]) �
2026-01-26 08:24:09,935 INFO driver.impl :: Registered driver :mysql (parents: [:sql-jdbc]) �
2026-01-26 08:24:09,995 INFO driver.impl :: Registered driver :postgres (parents: [:sql-jdbc]) �
2026-01-26 08:24:11,233 INFO core.core ::
Metabase v0.58.2.6 (cae120d)
Metabase Enterprise Edition extensions are NOT PRESENT.
java.sql.SQLException: Connections could not be acquired from the underlying database!
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:117)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:902)
at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:105)
at metabase.app_db.setup$migrate_BANG_.invokeStatic(setup.clj:74)
at metabase.app_db.setup$migrate_BANG_.doInvoke(setup.clj:59)
at clojure.lang.RestFn.invoke(RestFn.java:428)
at metabase.cmd.migrate$migrate_BANG_.invokeStatic(migrate.clj:8)
at metabase.cmd.migrate$migrate_BANG_.invoke(migrate.clj:5)
at clojure.lang.Var.invoke(Var.java:386)
at metabase.cmd.core$migrate.invokeStatic(core.clj:67)
at metabase.cmd.core$migrate.invoke(core.clj:62)
at clojure.lang.AFn.applyToHelper(AFn.java:154)
at clojure.lang.AFn.applyTo(AFn.java:144)
at clojure.core$apply.invokeStatic(core.clj:667)
at clojure.core$apply.invoke(core.clj:662)
at metabase.cmd.core$run_cmd$fn__128123.invoke(core.clj:309)
at metabase.cmd.core$run_cmd.invokeStatic(core.clj:306)
at metabase.cmd.core$run_cmd.invoke(core.clj:296)
at clojure.lang.Var.invoke(Var.java:395)
at metabase.core.core$run_cmd.invokeStatic(core.clj:253)
at metabase.core.core$run_cmd.invoke(core.clj:252)
at metabase.core.core$entrypoint.invokeStatic(core.clj:277)
at metabase.core.core$entrypoint.doInvoke(core.clj:270)
at clojure.lang.RestFn.applyTo(RestFn.java:140)
at clojure.lang.Var.applyTo(Var.java:707)
at clojure.core$apply.invokeStatic(core.clj:667)
at clojure.core$apply.invoke(core.clj:662)
at metabase.core.bootstrap$_main.invokeStatic(bootstrap.clj:36)
at metabase.core.bootstrap$_main.doInvoke(bootstrap.clj:29)
at clojure.lang.RestFn.applyTo(RestFn.java:140)
at metabase.core.bootstrap.main(Unknown Source)
Caused by: com.mchange.v2.resourcepool.CannotAcquireResourceException: A ResourcePool could not acquire a resource from its primary factory or source.
at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1660)
at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:710)
at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:616)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutAndScacheMarkConnectionInUse(C3P0PooledConnectionPool.java:966)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:894)
... 29 more
Caused by: org.h2.jdbc.JdbcSQLNonTransientConnectionException: Database may be already in use: "/datadrive/webapps/metabase_new/data/metabase.db/metabase.db.mv.db". Possible solutions: close all other connection(s); use the server mode [90020-214]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:678)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
at org.h2.message.DbException.get(DbException.java:212)
at org.h2.mvstore.db.Store.convertMVStoreException(Store.java:168)
at org.h2.mvstore.db.Store.(Store.java:145)
at org.h2.engine.Database.(Database.java:324)
at org.h2.engine.Engine.openSession(Engine.java:92)
at org.h2.engine.Engine.openSession(Engine.java:222)
at org.h2.engine.Engine.createSession(Engine.java:201)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
at org.h2.jdbc.JdbcConnection.(JdbcConnection.java:122)
at org.h2.Driver.connect(Driver.java:59)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:613)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:160)
at metabase.app_db.data_source.DataSource.getConnection(data_source.clj:77)
at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:119)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:510)
at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1301)
at com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(BasicResourcePool.java:1288)
at com.mchange.v2.resourcepool.BasicResourcePool.access$700(BasicResourcePool.java:12)
at com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(BasicResourcePool.java:2083)
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:696)
Caused by: org.h2.mvstore.MVStoreException: The file is locked: /datadrive/webapps/metabase_new/data/metabase.db/metabase.db.mv.db [2.1.214/7]
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
at org.h2.mvstore.FileStore.open(FileStore.java:172)
at org.h2.mvstore.FileStore.open(FileStore.java:128)
at org.h2.mvstore.MVStore.(MVStore.java:452)
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4082)
at org.h2.mvstore.db.Store.(Store.java:136)
... 17 more
Caused by: java.nio.channels.OverlappingFileLockException
at java.base/sun.nio.ch.FileLockTable.checkList(FileLockTable.java:229)
at java.base/sun.nio.ch.FileLockTable.add(FileLockTable.java:123)
at java.base/sun.nio.ch.FileChannelImpl.tryLock(FileChannelImpl.java:1734)
at java.base/java.nio.channels.FileChannel.tryLock(FileChannel.java:1343)
at org.h2.mvstore.FileStore.open(FileStore.java:169)
... 21 more
Command failed with exception: Connections could not be acquired from the underlying database!
Database may be already in use: "/metabase-data/metabase.db.mv.db" Error while creating file "/metabase-data/metabase.db.mv.db (a file with this name already exists)"
You might have passed the wrong path to Metabase/H2 (you included the .mv.db filename), so H2 tries to create a database with that name and then complains the file already exists.
thats actually what I want it to do, to take the existing mv.db File, so I can have a Metabase instance running with my data. However, it either creates a sample DB - that happens when the path is wrong and there is no data file- or when the data file is there, it doesnt import and get the error I sent …..
Guess I should have read the doc I linked more closely, it talks about a non-H2 related locking problem. “Migrate release-locks” is used if the instance crashes during a Liqubase migration.
Also, if using Docker, I strongly recommend disabling Docker health checks on the Metabase container until you migrate away from using H2. It will abruptly crash the container with little prevocation and H2 is quite fragile.