# CREATE ROLE

## Syntax

```bnf
CREATE [OR REPLACE] ROLE [IF NOT EXISTS] role 
  [WITH ADMIN 
    {CURRENT_USER | CURRENT_ROLE | user | role}]
```

## Description

The `CREATE ROLE` statement creates one or more MariaDB [roles](/docs/server/security/user-account-management/roles.md). To use it, you must have the global [CREATE USER](/docs/server/reference/sql-statements/account-management-sql-statements/grant.md#create-user) privilege or the [INSERT](/docs/server/reference/sql-statements/account-management-sql-statements/grant.md#table-privileges) privilege for the mysql database. For each account, `CREATE ROLE` creates a new row in the [mysql.user](/docs/server/reference/system-tables/the-mysql-database-tables/mysql-user-table.md) table that has no privileges, and with the corresponding `is_role` field set to `Y`. It also creates a record in the [mysql.roles\_mapping](/docs/server/reference/system-tables/the-mysql-database-tables/mysql-roles_mapping-table.md) table.

If any of the specified roles already exist, `ERROR 1396 (HY000)` results. If an error occurs, `CREATE ROLE` will still create the roles that do not result in an error. The maximum length for a role is 128 characters. Role names can be quoted, as explained in the [Identifier names](/docs/server/reference/sql-structure/sql-language-structure/identifier-names.md) page. Only one error is produced for all roles which have not been created:

```
ERROR 1396 (HY000): Operation CREATE ROLE failed for 'a','b','c'
```

Failed `CREATE` or `DROP` operations, for both users and roles, produce the same error code.

`PUBLIC` and `NONE` are reserved, and cannot be used as role names. `NONE` is used to [unset a role](/docs/server/reference/sql-statements/account-management-sql-statements/set-role.md) and `PUBLIC` has a special use in other systems, such as Oracle, so is reserved for compatibility purposes.

For valid identifiers to use as role names, see [Identifier Names](/docs/server/reference/sql-structure/sql-language-structure/identifier-names.md).

#### WITH ADMIN

The optional `WITH ADMIN` clause determines whether the current user, the current role or another user or role has use of the newly created role. If the clause is omitted, `WITH ADMIN CURRENT_USER` is treated as the default, which means that the current user will be able to [GRANT](/docs/server/reference/sql-statements/account-management-sql-statements/grant.md#roles) this role to users.

### Example: Using WITH ADMIN

The WITH ADMIN option allows a specific user or role to manage (grant or revoke) the newly created role. For example:

```sql
CREATE ROLE developer WITH ADMIN lorinda@localhost;
```

Here, the `developer` role is created, and the user `lorinda@localhost` is given permission to grant or revoke this role to other users.

If another user without administrative privileges attempts to grant the role, the operation fails:

```sql
GRANT developer TO ian@localhost;
-- ERROR: Access denied
```

However, when executed by `lorinda@localhost`, the operation succeeds:

```sql
GRANT developer TO ian@localhost;
```

#### OR REPLACE

If the optional `OR REPLACE` clause is used, it acts as a shortcut for:

```sql
DROP ROLE IF EXISTS name;
CREATE ROLE name ...;
```

#### IF NOT EXISTS

When the `IF NOT EXISTS` clause is used, MariaDB will return a warning instead of an error if the specified role already exists. Cannot be used together with the `OR REPLACE` clause.

## Examples

```sql
CREATE ROLE journalist;

CREATE ROLE developer WITH ADMIN lorinda@localhost;
```

Granting the role to another user. Only user `lorinda@localhost` has permission to grant the `developer` role:

```sql
SELECT USER();
```

```
+-------------------+
| USER()            |
+-------------------+
| henning@localhost |
+-------------------+
...
```

```sql
GRANT developer TO ian@localhost;
```

```
Access denied for user 'henning'@'localhost'
```

```sql
SELECT USER();
```

```
+-------------------+
| USER()            |
+-------------------+
| lorinda@localhost |
+-------------------+
```

```sql
GRANT m_role TO ian@localhost;
```

The `OR REPLACE` and `IF NOT EXISTS` clauses. The `journalist` role already exists:

```sql
CREATE ROLE journalist;
ERROR 1396 (HY000): Operation CREATE ROLE failed for 'journalist'

CREATE OR REPLACE ROLE journalist;
Query OK, 0 rows affected (0.00 sec)

CREATE ROLE IF NOT EXISTS journalist;
Query OK, 0 rows affected, 1 warning (0.00 sec)
```

```sql
SHOW WARNINGS;
```

<pre><code><strong>+-------+------+---------------------------------------------------+
</strong>| Level | Code | Message                                           |
+-------+------+---------------------------------------------------+
| Note  | 1975 | Can't create role 'journalist'; it already exists |
+-------+------+---------------------------------------------------+
</code></pre>

## See Also

* [Identifier Names](/docs/server/reference/sql-structure/sql-language-structure/identifier-names.md)
* [Roles Overview](/docs/server/security/user-account-management/roles/roles_overview.md)
* [DROP ROLE](/docs/server/reference/sql-statements/account-management-sql-statements/drop-role.md)

<sub>*This page is licensed: CC BY-SA / Gnu FDL*</sub>

{% @marketo/form formId="4316" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mariadb.com/docs/server/reference/sql-statements/account-management-sql-statements/create-role.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
