On this page
Why it happens
Error 3701 means a DROP statement could not proceed because SQL Server could not resolve the named object to something you are allowed to drop. The wording covers two situations at once: the object is not there, or it is there but you may not drop it. The message deliberately does not say which, so the same text can apply to a table, view, procedure, function, index, or any other droppable object.
The most common cause is that the object simply is not present. It may have been dropped already, never created, or created in a different database or schema. A re-run script that drops the same object twice hits this on the second pass. A typo in the object name produces the same result, because SQL Server looks for the exact name you typed.
The other half of the message is permission. If the object does exist but your login is not the owner and has not been granted ALTER or CONTROL on it (or on its schema), SQL Server refuses and reports 3701 rather than reveal whether the object is there. Severity 11 marks this as a normal, catchable error, not a server fault.
Examples
Dropping a table that does not exist
-- dbo.Orders was never created, or was already dropped
DROP TABLE dbo.Orders;
Msg 3701, Level 11, State 5, Line 2 Cannot drop the table 'dbo.Orders', because it does not exist or you do not have permission.
Right table, wrong schema
-- The table lives in the Sales schema, not dbo
CREATE TABLE Sales.Orders (id INT PRIMARY KEY);
DROP TABLE dbo.Orders; -- looks in dbo, finds nothing
Msg 3701, Level 11, State 5, Line 4 Cannot drop the table 'dbo.Orders', because it does not exist or you do not have permission.
Dropping a procedure that is not there
-- No such procedure in this database
DROP PROCEDURE dbo.usp_ArchiveOrders;
Msg 3701, Level 11, State 5, Line 2 Cannot drop the procedure 'dbo.usp_ArchiveOrders', because it does not exist or you do not have permission.
How to fix it
Use DROP ... IF EXISTS so a missing object is a no-op
On SQL Server 2016 and later, add IF EXISTS. If the object is not there the statement does nothing and does not error, which makes re-run and deploy scripts safe.
DROP TABLE IF EXISTS dbo.Orders;
-- Works for other object types too
DROP PROCEDURE IF EXISTS dbo.usp_ArchiveOrders;
DROP VIEW IF EXISTS dbo.vOrderSummary;
Verify the object exists and qualify the schema
Confirm the object is where you think it is, then use the correct two-part name. A missing schema prefix is the most common reason SQL Server cannot find the object.
-- Find where the object actually lives
SELECT s.name AS schema_name, o.name AS object_name, o.type_desc
FROM sys.objects o
JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE o.name = 'Orders';
-- Then drop it with the correct schema
DROP TABLE Sales.Orders;
Connect to the correct database first
If the object lives in another database, your session must be pointed at that database. Switch context with USE before the drop.
USE SalesDB;
GO
DROP TABLE IF EXISTS dbo.Orders;
Grant the permission needed to drop the object
If the object does exist, you need ownership or ALTER/CONTROL on it or its schema. Have a privileged login grant it, then retry the drop.
-- Run as a user with rights on the schema
GRANT ALTER ON SCHEMA::dbo TO AppDeployUser;
-- Or grant control of the specific object
GRANT CONTROL ON OBJECT::dbo.Orders TO AppDeployUser;
Guard the drop on older versions with OBJECT_ID
Before SQL Server 2016 there is no IF EXISTS clause on DROP. Use OBJECT_ID to check first so a missing object never raises the error.
IF OBJECT_ID('dbo.Orders', 'U') IS NOT NULL
DROP TABLE dbo.Orders;
How to prevent it
Put an IF EXISTS guard on every DROP in deployment and teardown scripts (or an OBJECT_ID check on older servers) so re-running a script is harmless. Always write objects with their two-part name, schema.object, so a drop can never resolve to the wrong schema.
Run deploy scripts under a login that owns the schema or has ALTER/CONTROL, and confirm the target database at the top of the script with USE. For a refresher on object naming and schemas, see the SQL syntax guide and the SQL tutorial.
Common questions
How do I drop a table only if it exists?
On SQL Server 2016 and later use DROP TABLE IF EXISTS dbo.Orders, which does nothing if the table is missing instead of raising 3701. On older versions wrap it: IF OBJECT_ID('dbo.Orders', 'U') IS NOT NULL DROP TABLE dbo.Orders. The same pattern works for views, procedures, and other objects.
Why does one message cover both "does not exist" and "no permission"?
SQL Server does not reveal whether an object exists to a user who is not allowed to see it, because that would leak information. So a missing object and an object you lack rights to drop return the identical 3701 text. If DROP ... IF EXISTS still fails, the cause is permission, not a missing object.
DROP TABLE IF EXISTS still errors with 3701. What now?
IF EXISTS suppresses the missing-object case, so a remaining 3701 almost always means a permission problem or the wrong schema. Confirm the object with sys.objects, check you are in the right database, and make sure your login has ALTER or CONTROL on the object or its schema.