diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index 7511ee82e1124eefaac3caaa7c5446090064b7d7..3299532e59837f48890a7fb56708792a7fa660d0 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -1004,12 +1004,16 @@ end
 
 box.schema.func = {}
 box.schema.func.create = function(name, opts)
+    opts = opts or {}
     local _func = box.space[box.schema.FUNC_ID]
     local func = _func.index.name:get{name}
     if func then
+        if not opts.if_not_exists then
             box.error(box.error.FUNCTION_EXISTS, name)
+        end
+        return
     end
-    check_param_table(opts, { setuid = 'boolean' })
+    check_param_table(opts, { setuid = 'boolean', if_not_exists = 'boolean' })
     opts = update_param_table(opts, { setuid = false })
     opts.setuid = opts.setuid and 1 or 0
     _func:auto_increment{session.uid(), name, opts.setuid}
@@ -1073,11 +1077,13 @@ end
 
 box.schema.user.create = function(name, opts)
     local uid = user_or_role_resolve(name)
+    opts = opts or {}
+    check_param_table(opts, { password = 'string', if_not_exists = 'boolean' })
     if uid then
-        box.error(box.error.USER_EXISTS, name)
-    end
-    if opts == nil then
-        opts = {}
+        if not opts.if_not_exists then
+            box.error(box.error.USER_EXISTS, name)
+        end
+        return
     end
     auth_mech_list = {}
     if opts.password then
@@ -1259,10 +1265,15 @@ box.schema.role.exists = function(name)
     end
 end
 
-box.schema.role.create = function(name)
+box.schema.role.create = function(name, opts)
+    opts = opts or {}
+    check_param_table(opts, { if_not_exists = 'boolean' })
     local uid = user_or_role_resolve(name)
     if uid then
-        box.error(box.error.ROLE_EXISTS, name)
+        if not opts.if_not_exists then
+            box.error(box.error.ROLE_EXISTS, name)
+        end
+        return
     end
     local _user = box.space[box.schema.USER_ID]
     _user:auto_increment{session.uid(), name, 'role'}
diff --git a/test/box/access.result b/test/box/access.result
index df277527142bb8493b48e652afd088b62751ebad..28d22005a549533843e6f30ae681023780a6721e 100644
--- a/test/box/access.result
+++ b/test/box/access.result
@@ -640,3 +640,12 @@ box.schema.user.revoke('guest', 'read,write,execute', 'universe')
 box.schema.user.revoke('guest', 'read,write,execute', 'universe', '', { if_exists = true })
 ---
 ...
+box.schema.func.create('dummy', { if_not_exists = true })
+---
+...
+box.schema.func.create('dummy', { if_not_exists = true })
+---
+...
+box.schema.func.drop('dummy')
+---
+...
diff --git a/test/box/access.test.lua b/test/box/access.test.lua
index 2700b7e5bead38a24826f16699184648f0826429..ec0e5193d63e13767fbf34a9920f0ea298db47ee 100644
--- a/test/box/access.test.lua
+++ b/test/box/access.test.lua
@@ -250,3 +250,6 @@ box.schema.user.grant('guest', 'read,write,execute', 'universe', '', { if_not_ex
 box.schema.user.revoke('guest', 'read,write,execute', 'universe')
 box.schema.user.revoke('guest', 'read,write,execute', 'universe')
 box.schema.user.revoke('guest', 'read,write,execute', 'universe', '', { if_exists = true })
+box.schema.func.create('dummy', { if_not_exists = true })
+box.schema.func.create('dummy', { if_not_exists = true })
+box.schema.func.drop('dummy')
diff --git a/test/box/role.result b/test/box/role.result
index 5e4ef6d6c070bd1dd0899c42d544c33f3728cb16..f11af5c62afda24a603a9ed907fe61c3dac45d0a 100644
--- a/test/box/role.result
+++ b/test/box/role.result
@@ -799,3 +799,30 @@ box.schema.role.exists(0)
 ---
 - false
 ...
+box.schema.role.create('public', { if_not_exists = true})
+---
+...
+box.schema.user.create('admin', { if_not_exists = true})
+---
+...
+box.schema.user.create('guest', { if_not_exists = true})
+---
+...
+box.schema.user.create('test', { if_not_exists = true})
+---
+...
+box.schema.user.create('test', { if_not_exists = true})
+---
+...
+box.schema.role.drop('test', { if_not_exists = true})
+---
+...
+box.schema.role.create('test', { if_not_exists = true})
+---
+...
+box.schema.role.create('test', { if_not_exists = true})
+---
+...
+box.schema.user.drop('test', { if_not_exists = true})
+---
+...
diff --git a/test/box/role.test.lua b/test/box/role.test.lua
index 6036c3d587cabcc5a42f4ce8be444fc55848fc5c..6d3014edd5037b266be4809dedf0fdd9424a2b48 100644
--- a/test/box/role.test.lua
+++ b/test/box/role.test.lua
@@ -317,3 +317,12 @@ box.schema.role.exists('admin')
 box.schema.role.exists(3)
 -- user id 
 box.schema.role.exists(0)
+box.schema.role.create('public', { if_not_exists = true})
+box.schema.user.create('admin', { if_not_exists = true})
+box.schema.user.create('guest', { if_not_exists = true})
+box.schema.user.create('test', { if_not_exists = true})
+box.schema.user.create('test', { if_not_exists = true})
+box.schema.role.drop('test', { if_not_exists = true})
+box.schema.role.create('test', { if_not_exists = true})
+box.schema.role.create('test', { if_not_exists = true})
+box.schema.user.drop('test', { if_not_exists = true})