Download

Cannot drop the table because it does not exist or you do not have permission

SQL Server couldn’t drop the object: either there’s nothing by that name where you’re looking (wrong database, wrong schema, already dropped) or you aren’t allowed to drop it, and the message doesn’t say which. Use DROP … IF EXISTS in scripts, and check the database and schema.

SQL Server error 3701· Tested on SQL Server 2022 RTM-CU27 (16.0.4295.3); same messages on 2019 RTM-CU32-GDR and 2025 RTM-CU9· Updated 11 October 2026

Cannot drop the table 'seo_err_mssql.invoices', because it does not exist or you do not have permission.

What it means

Your DROP TABLE, DROP VIEW, DROP PROCEDURE, DROP FUNCTION, DROP INDEX or DROP DATABASE named something SQL Server couldn’t drop. There are two possible reasons and the message deliberately doesn’t say which, so that it can’t be used to find out about objects you’re not allowed to see:

  • Nothing by that name exists where SQL Server looked: in the current database, in the schema you named, or in your default schema (usually dbo) if you didn’t name one.
  • It exists, but you can’t drop it. Dropping a table needs ALTER on its schema, CONTROL on the table, or membership of db_ddladmin (or db_owner).
Msg 3701, Level 11, State 5, Server 7732422b7f56, Line 1
Cannot drop the table 'seo_err_mssql.invoices', because it does not exist or you do not have permission.

In our tests the two cases did differ in the details: a missing table gave level 11, state 5, and quoted the name as written; a table the reader login could see but not drop gave level 14, state 20, and quoted only 'orders'. Nothing in the statement is dropped either way, except in a list: DROP TABLE a, b drops a even when b fails.

Common causes

  1. It’s already gone: a cleanup or migration script run a second time.
  2. The wrong database. The connection opened in master or another default database, or a USE earlier in the script went somewhere else.
  3. The wrong schema. DROP TABLE invoices looks in your default schema; the table is billing.invoices.
  4. A temp table from another session. #temp tables belong to the session (or procedure) that made them, and are dropped when it ends.
  5. No permission. A login that can read the table can see it but not drop it.
  6. A typo or a different case on a database with a case-sensitive collation.

Similar messages with other numbers: DROP TABLE on a view is 3705 (Cannot use DROP TABLE with … because … is a view. Use DROP VIEW.), a missing constraint in ALTER TABLE … DROP CONSTRAINT is 3728 then 3727, a missing column in DROP COLUMN is 4924, and a missing user, role or schema is 15151. A table that other tables’ foreign keys point to fails with 3726.

How to fix it

Use IF EXISTS in scripts

From SQL Server 2016 on, every common DROP takes IF EXISTS and does nothing when the object is missing:

DROP TABLE IF EXISTS billing.invoices_old;
DROP VIEW IF EXISTS billing.open_invoices;
DROP PROCEDURE IF EXISTS billing.close_month;
DROP INDEX IF EXISTS IX_invoices_due ON billing.invoices;
ALTER TABLE billing.invoices DROP CONSTRAINT IF EXISTS DF_invoices_status;
ALTER TABLE billing.invoices DROP COLUMN IF EXISTS legacy_code;

On older versions, check first. For a temp table, look in tempdb:

IF OBJECT_ID(N'billing.invoices_old', N'U') IS NOT NULL DROP TABLE billing.invoices_old;
IF OBJECT_ID(N'tempdb..#work') IS NOT NULL DROP TABLE #work;

Check where you are, and name the schema

SELECT DB_NAME() AS current_database, SCHEMA_NAME() AS default_schema;

SELECT SCHEMA_NAME(schema_id) AS [schema], name, type_desc
FROM sys.objects
WHERE name = N'invoices';

If the second query finds nothing, the object isn’t in this database (or you can’t see it). Always write the schema in DROP statements, as billing.invoices rather than invoices.

Check your permission

SELECT HAS_PERMS_BY_NAME(N'billing', N'SCHEMA', N'ALTER') AS can_alter_schema,
       HAS_PERMS_BY_NAME(N'billing.invoices', N'OBJECT', N'CONTROL') AS can_control_table;

Two zeros mean you can’t drop it. Someone with rights can grant ALTER on the schema, or add you to db_ddladmin:

GRANT ALTER ON SCHEMA::billing TO <user>;

Reproduce it

On SQL Server 2022 (16.0.4295.3) with sqlcmd, logged in as a user that owns the database, each statement in its own batch:

DROP TABLE seo_err_mssql.invoices;
DROP VIEW seo_err_mssql.v_missing;
DROP TABLE #nope;
DROP INDEX IX_nope ON seo_err_mssql.customers;
Msg 3701, Level 11, State 5, Server 7732422b7f56, Line 1
Cannot drop the table 'seo_err_mssql.invoices', because it does not exist or you do not have permission.
Msg 3701, Level 11, State 5, Server 7732422b7f56, Line 1
Cannot drop the view 'seo_err_mssql.v_missing', because it does not exist or you do not have permission.
Msg 3701, Level 11, State 5, Server 7732422b7f56, Line 1
Cannot drop the table '#nope', because it does not exist or you do not have permission.
Msg 3701, Level 11, State 7, Server 7732422b7f56, Line 1
Cannot drop the index 'seo_err_mssql.customers.IX_nope', because it does not exist or you do not have permission.

DROP PROCEDURE and DROP FUNCTION on missing names gave the same message, naming a procedure and a function; DROP DATABASE gave it with state 1. Logged in as reader, which can read seo_err_mssql.orders but has neither ALTER on the schema nor CONTROL on the table, inside a transaction:

Msg 3701, Level 14, State 20, Server 7732422b7f56, Line 2
Cannot drop the table 'orders', because it does not exist or you do not have permission.

The table was still there afterwards. DROP TABLE seo_err_mssql.labels3, seo_err_mssql.nope dropped labels3 and then failed on nope. Every IF EXISTS form above, on missing objects, ran without a message. SQL Server 2019 and 2025 printed the same messages.

In Inlet

On protected connections, a DROP in the query editor asks before it runs and says why, and dropping a table from the sidebar asks you to type its name. The sidebar lists each schema’s tables, views, functions and procedures, so you can see which schema holds the one you mean. When SQL Server refuses, Inlet shows its message with SQL Server error 3701, state 5, severity 11 and links to this page.

Inlet: a database client for the Mac

One native app for PostgreSQL, MySQL, SQL Server, SQLite, MongoDB and Redis. It explains errors where they happen, holds your edits until you save them, and keeps production read-only until you say so.

Version 0.1.0 · macOS 26 Tahoe or later · Apple silicon and Intel