diff --git a/src/luamod.lua b/src/luamod.lua
index f7237aedb3daf0dac9d3b1c76bfefc7f5c0f5fdb..ef45685d6d6d340a6206f0a9c632eb73dfacbdb7 100644
--- a/src/luamod.lua
+++ b/src/luamod.lua
@@ -104,7 +104,8 @@ local function is_retriable_error(error)
     return false
 end
 
--- Performs a reenterable schema change CaS request.
+-- Performs a reenterable schema change CaS request. On success returns an index
+-- of the proposed raft entry.
 --
 -- Params:
 --
@@ -119,6 +120,12 @@ end
 --          It is called after raft_read_index and after any pending schema
 --          change has been finalized.
 --
+-- Returns:
+--
+--      (number) raft index
+--      or
+--      (nil, error) in case of an error
+--
 local function reenterable_schema_change_request(deadline, make_op_if_needed)
     while true do
         ::retry::
@@ -909,6 +916,10 @@ Drops a space on each instance of the cluster.
 
 Waits for the space to be dropped globally or returns an error if the timeout is
 reached before that.
+Skips the request if the space doesn't exist.
+
+NOTE: If this function returns a timeout error, the space may have been locally
+dropped and in the future the change can either be committed or rolled back.
 
 Params:
 
@@ -938,42 +949,49 @@ function pico.drop_space(space, opts)
         return nil, err
     end
 
-    local space_id
-    if type(space) == 'string' then
-        local space_def = box.space._pico_space.index.name:get(space)
-        if space_def == nil then
-            return nil, box.error.new(box.error.NO_SUCH_SPACE, space)
+    local deadline = fiber.clock() + opts.timeout
+
+    local should_wait_for_ddl_fin = true
+
+    -- XXX: we construct this closure every time the function is called,
+    -- which is bad for performance/jit. Refactor if problems are discovered.
+    local function make_op_if_needed()
+        local space_def = nil
+        if type(space) == 'string' then
+            space_def = box.space._pico_space.index.name:get(space)
+        elseif type(space) == 'number' then
+            space_def = box.space._pico_space:get(space)
         end
-        space_id = space_def.id
-    elseif type(space) == 'number' then
-        space_id = space
-        if box.space._pico_space:get(space_id) == nil then
-            return nil, box.error.new(box.error.NO_SUCH_SPACE, space)
+        if space_def == nil then
+            -- Space doesn't exist yet, no op needed
+            should_wait_for_ddl_fin = false
+            return nil
         end
-    end
 
-    local op = {
-        kind = 'ddl_prepare',
-        schema_version = next_schema_version(),
-        ddl = {
-            kind = 'drop_space',
-            id = space_id,
+        return {
+            kind = 'ddl_prepare',
+            schema_version = next_schema_version(),
+            ddl = {
+                kind = 'drop_space',
+                id = space_def.id,
+            }
         }
-    }
+    end
 
-    local timeout = opts.timeout
-    local ok, err = pico._prepare_schema_change(op, timeout)
-    if not ok then
+    local index, err = reenterable_schema_change_request(deadline, make_op_if_needed)
+    if index == nil then
         return nil, err
     end
-    local index = ok
 
-    local ok, err = pico.wait_ddl_finalize(index, { timeout = timeout })
-    if not ok then
+    if not should_wait_for_ddl_fin then
+        return index
+    end
+
+    local fin_index, err = pico.wait_ddl_finalize(index, { timeout = deadline - fiber.clock() })
+    if fin_index == nil then
         return nil, err
     end
 
-    local fin_index = ok
     return fin_index
 end
 
diff --git a/test/int/test_ddl.py b/test/int/test_ddl.py
index 51fbaa167444acb95da7311b435a715af5bb6823..1e70c63f2c3b40135dc1358e90a481b6c30e5f70 100644
--- a/test/int/test_ddl.py
+++ b/test/int/test_ddl.py
@@ -100,15 +100,11 @@ def test_ddl_lua_api(cluster: Cluster):
     # pico.drop_space
     #
 
-    # No such space name -> error.
-    with pytest.raises(
-        ReturnError, match="Space 'Space does not exist' does not exist"
-    ):
-        cluster.drop_space("Space does not exist")
+    # No such space name -> ok.
+    cluster.drop_space("Space does not exist")
 
-    # No such space id -> error.
-    with pytest.raises(ReturnError, match="Space '69105' does not exist"):
-        cluster.drop_space(69105)
+    # No such space id -> ok.
+    cluster.drop_space(69105)
 
     # Ok by name.
     cluster.drop_space("some_name")