- Error number
- 3154
- Severity
- 16 (user-correctable error)
- State
- 4
- Product
- Microsoft SQL Server Database Engine
- Versions
- All supported SQL Server versions (2016 to 2025), Azure SQL Managed Instance
- Category
- Backup & Restore
- Last reviewed
- 23 October 2026
On this page
What it means
Error 3154 means you are restoring over an existing database that is not the database the backup was taken from, so SQL Server refuses to overwrite it unless you say so explicitly.
RESTORE protects existing databases. When the target name already exists, SQL Server compares the database inside the backup with the database on the server. If they are not the same database, it stops with 3154 instead of silently replacing it, and the statement ends with Msg 3013 ... RESTORE DATABASE is terminating abnormally. The name in quotes is the existing database that would have been overwritten.
"Other than the existing database" is about identity, not only names. Restoring AppDb.bak into an AppDb that you created a moment ago in SSMS also fails, because the new empty database is a different database that happens to share the name. The usual answers are to restore under a new name (with MOVE for the files), to drop the empty database first, or to overwrite deliberately with WITH REPLACE when you are sure the existing contents can go.
Common causes
- An empty database was created first (for example New Database in SSMS) and the backup was then restored into it. RESTORE creates the database itself; there is no need to create it.
- A production backup is being restored over a test or development database with a different name, for example to refresh it.
- The wrong backup file or the wrong target database was chosen, for example a backup of Sales restored over HR. Here the error is doing its job.
- The target database was dropped and recreated (or restored from another server) since the backup was taken, so it is no longer the same database even with the same name.
Diagnose it
Read-only These queries only read metadata and dynamic management views. They do not change data, permissions or configuration, so they are safe to run first.
Which database is inside the backup?
Run RESTORE HEADERONLY FROM DISK = N'D:\Backups\AppDb.bak'; and read DatabaseName, ServerName and BackupFinishDate; it reads only the header. If the backup was taken on this server, the history query below shows the same.
SELECT TOP (10) bs.database_name, bs.server_name, bs.backup_finish_date,
bs.family_guid, mf.physical_device_name
FROM msdb.dbo.backupset AS bs
JOIN msdb.dbo.backupmediafamily AS mf ON mf.media_set_id = bs.media_set_id
ORDER BY bs.backup_finish_date DESC; The database the backup holds and its family_guid. If database_name differs from your target, or the target was recreated after the backup, 3154 is expected.
What does the existing target database contain?
SELECT d.name, d.create_date, d.state_desc, d.recovery_model_desc, rs.family_guid
FROM sys.databases AS d
JOIN sys.database_recovery_status AS rs ON rs.database_id = d.database_id
WHERE d.name = N'AppDb';
SELECT name, physical_name, size / 128 AS size_mb
FROM sys.master_files
WHERE database_id = DB_ID(N'AppDb'); A recent create_date and a tiny size means an empty database created just before the restore. A family_guid different from the one in the backup history is a sign that it is a different database. The file paths are what a MOVE would need to reuse.
How to fix it
Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.
Restore under a new name with MOVE
Changes database stateThe safest option: nothing existing is touched. Give the database a name that does not exist and new file paths, because the logical files in the backup still point at the original database's files. Get the logical names from RESTORE FILELISTONLY.
RESTORE DATABASE AppDb_Copy
FROM DISK = N'D:\Backups\AppDb.bak'
WITH MOVE N'AppDb' TO N'D:\SQLData\AppDb_Copy.mdf',
MOVE N'AppDb_log' TO N'D:\SQLLogs\AppDb_Copy_log.ldf',
CHECKSUM;
Drop the empty database you created, then restore
Changes database stateIf you created the target database only to restore into it, confirm it is empty (diagnostic 2), drop it and run the RESTORE again; RESTORE creates the database and its files.
Caution: Check twice that you are dropping the new, empty database and not one with data. DROP DATABASE deletes its files.
DROP DATABASE AppDb;
RESTORE DATABASE AppDb
FROM DISK = N'D:\Backups\AppDb.bak'
WITH CHECKSUM;
Overwrite the existing database deliberately with REPLACE
Changes database stateTo refresh a test database from production, WITH REPLACE tells SQL Server to discard the existing database and everything in it. If the source database lives on the same instance, also MOVE the files to the target's own paths; otherwise the restore fails with 1834 and 3156 because the original files are in use. Take a backup of the target first if anything in it might be needed again.
Caution: REPLACE overwrites the existing database and its files without further checks, including the tail of its log. Any data in the target that is not in a backup is lost. Never use it on a database you have not identified with certainty.
-- Optional but recommended: keep a copy of the target first
BACKUP DATABASE AppDb_Test TO DISK = N'D:\Backups\AppDb_Test_before_refresh.bak' WITH COPY_ONLY;
RESTORE DATABASE AppDb_Test
FROM DISK = N'D:\Backups\AppDb.bak'
WITH REPLACE,
MOVE N'AppDb' TO N'D:\SQLData\AppDb_Test.mdf',
MOVE N'AppDb_log' TO N'D:\SQLLogs\AppDb_Test_log.ldf';
Examples
Restoring into an empty database created first
Throwaway database and backup file; the backup goes to the instance default backup folder. The DROP and CREATE stand in for creating a new empty database in SSMS before the restore.
USE master;
DECLARE @bak nvarchar(260) = CAST(SERVERPROPERTY('InstanceDefaultBackupPath') AS nvarchar(200)) + N'\cws_errlab_3154a.bak';
BACKUP DATABASE AppDb TO DISK = @bak WITH INIT;
DROP DATABASE AppDb; -- the original is gone (or on another server)
CREATE DATABASE AppDb; -- a new, empty database with the same name
RESTORE DATABASE AppDb FROM DISK = @bak;
Msg 3154, Level 16, State 4, Line 7 The backup set holds a backup of a database other than the existing 'AppDb' database. Msg 3013, Level 16, State 1, Line 7 RESTORE DATABASE is terminating abnormally.
Reproduced on SQL Server 2025 (17.0.1145.4), 23 October 2026.
Restoring one database over another without REPLACE
Two throwaway databases: the backup of AppDb is restored over an existing test database (named cws_errlab_test here), which is then dropped.
USE master;
DECLARE @bak nvarchar(260) = CAST(SERVERPROPERTY('InstanceDefaultBackupPath') AS nvarchar(200)) + N'\cws_errlab_3154b.bak';
BACKUP DATABASE AppDb TO DISK = @bak WITH INIT;
CREATE DATABASE cws_errlab_test; -- a different, existing database
RESTORE DATABASE cws_errlab_test FROM DISK = @bak; -- no REPLACE
GO
DROP DATABASE cws_errlab_test;
Msg 3154, Level 16, State 4, Line 6 The backup set holds a backup of a database other than the existing 'cws_errlab_test' database. Msg 3013, Level 16, State 1, Line 6 RESTORE DATABASE is terminating abnormally.
Reproduced on SQL Server 2025 (17.0.1145.4), 23 October 2026.
How to prevent it
Do not create a database before restoring it: let RESTORE create it. For refresh jobs that overwrite a test copy, script the restore once with explicit REPLACE and MOVE clauses and a target name that can never be a production database, and review that script rather than clicking through the restore dialog each time.
Name backup files after the database and date they hold, and check RESTORE HEADERONLY before a restore, so the wrong file is caught before it reaches the wrong database.
Common questions
Is it safe to just add WITH REPLACE?
Only when you are certain the existing database can be thrown away. REPLACE skips the identity check that raised 3154 and also the tail-log check, so anything in the target that is not in a backup is gone.
Why does it fail when both databases have the same name?
SQL Server compares the database identity, not just the name. A database created or recreated after the backup is a different database, even with the same name.
How do I restore a copy next to the original on the same server?
Restore under a new database name and use WITH MOVE to give every file a new path. Without MOVE the restore tries to use the original database's file paths, which are in use.
Learn more on CodeWithSQL
Official documentation
- RESTORE statements (Transact-SQL)
- Restore a database to a new location (SQL Server)
- RESTORE statements: arguments (Transact-SQL)
Last technically reviewed 23 October 2026; examples and diagnostics run on SQL Server 2025 (17.0.1145.4). Message text checked against the engine's sys.messages catalogue.