Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
FREEDOM251

Freedom251 › Blog › Access Denied

How to Create a New MySQL User and Fix Permission Errors (MySQL 8.4)

By Freedom251 Team · · 9 min read

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To create a MySQL 8.4 account, connect with an administrator, run CREATE USER for the exact user@host pair that will connect, then grant only the required privileges. A new account has no permissions until you issue GRANT. When an operation fails with Access denied, inspect the username and host in the complete error, compare USER() with CURRENT_USER(), and check SHOW GRANTS for the authenticated account before changing anything.

The account you create is a user-and-host pair

MySQL does not identify an account by username alone. The host is part of the account name, so these are separate accounts:

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Account What it represents Typical use
'appuser'@'localhost' Connections originating on the same machine as the server A local application or administration script
'appuser'@'127.0.0.1' Connections that use the IPv4 loopback address A client explicitly configured for 127.0.0.1
'appuser'@'10.20.30.15' Connections from one specific client address A service with a fixed private IP
'appuser'@'%' Connections matching a broad host pattern Only when a wider source range is genuinely required

Creating 'appuser'@'localhost' does not authorize 'appuser'@'127.0.0.1' or 'appuser'@'%. If the error names a different host, grant privileges to that exact account or correct the client connection so it uses the intended one.

What you need before running the SQL

  • A MySQL 8.4 server and a client that can connect to it.
  • An administrative account authorized to create users. CREATE USER requires the global CREATE USER privilege, or the documented system-schema alternative of INSERT on the mysql schema.
  • The database and, ideally, the specific tables the application must access.
  • A password-handling method that does not expose reusable production secrets in shared shell history, terminal recordings, or log files.

Use the following examples as the mysql> prompt. Replace names with your own values, and keep the host portion synchronized with the application’s connection settings.

Create a user and grant its first permissions

1. Connect with an authorized administrator

Log in using an account that has the authority to create users and grant the privileges you need. If the login itself fails, resolve that administrative connection first; an application account cannot repair its own missing permissions.

mysql -u admin_user -p -h db.example.internal

The command above is an example connection pattern. The exact administrative username, host, port, and TLS options depend on your deployment.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

2. Create the exact host-qualified account

CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'strong-secret';

CREATE USER creates the account and its authentication information, but it does not grant access to any database, table, or global operation. Keep the host literal or pattern as narrow as the workload permits.

If the account already exists, this statement fails rather than silently replacing it. That is useful protection: inspect the existing account before deciding whether to alter it, reuse it, or create a differently named account.

3. Grant only the required scope

GRANT SELECT, INSERT, UPDATE
ON appdb.*
TO 'appuser'@'localhost';

This grants the listed privileges on every current and future table in the appdb database. It does not grant DELETE, schema-creation privileges, administrative privileges, or access to other databases.

To grant access to one table instead, narrow the object:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
GRANT SELECT, INSERT, UPDATE
ON appdb.orders
TO 'appuser'@'localhost';

A GRANT operation requires both GRANT OPTION and the privileges being granted, subject to MySQL’s documented system-schema alternative. Do not hand out broad grant authority merely to make an application setup work.

4. Inspect the result immediately

SHOW GRANTS FOR 'appuser'@'localhost';
SHOW CREATE USER 'appuser'@'localhost';

SHOW GRANTS displays the account’s effective privilege statements and role assignments. In MySQL 8.4, global output explicitly lists the individual privileges instead of relying on one generic ALL PRIVILEGES label. SHOW CREATE USER displays the account definition and authentication or account attributes; it returns an error when that exact account does not exist.

Choose the narrowest grant that supports the workload

Grant scope determines how much damage a compromised credential could cause and how many unrelated objects the account can change. Start at the smallest scope and expand only when a documented operation requires it.

Grant target Example Effect When to use
Global *.* Applies across the server, subject to the individual privilege Only for duties that truly span databases or require server-wide administration
Database appdb.* Applies to all objects in one database An application needs several tables and future tables in the same database
Table appdb.orders Applies to one table A service has a narrowly defined data path
Column appdb.customers with selected columns Limits access to named columns for supported privileges The service must not read or modify sensitive columns

Database-level access is convenient, but it automatically covers every object in that database. Table- or column-level grants require more maintenance as the schema changes, yet they reduce accidental exposure. Document the reason for every exception instead of starting with GRANT ALL PRIVILEGES ON *.*.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Verify the account from both sides

Check an account from an administrator session

SHOW GRANTS FOR 'appuser'@'localhost';
SHOW CREATE USER 'appuser'@'localhost';

Use the same host spelling in both statements that you used in CREATE USER. A successful result confirms that the named account exists and shows what is assigned to it. It does not prove that your application is connecting as that account; the client may be using another username, host, port, or authentication path.

Check the session that is failing

SELECT USER(), CURRENT_USER();
SHOW GRANTS FOR CURRENT_USER;

USER() reports the identity and host supplied by the client connection. CURRENT_USER() reports the MySQL account used for authentication and privilege checking. Comparing the two exposes many host-mismatch errors: the client may request one identity while MySQL authenticates it against another host-qualified account.

Running SHOW GRANTS FOR CURRENT_USER while connected as the failing account avoids guessing which account’s privileges are relevant. If the account cannot connect at all, run SHOW GRANTS FOR 'user'@'host' from an administrator session using the username and host shown in the error.

Diagnose “Access denied for user” step by step

MySQL’s official troubleshooting guidance notes that an Access denied error can have many causes and is often related to which MySQL accounts the server permits client programs to use. Separate connection authentication problems from authorization problems: first establish which account authenticated, then determine whether that account is allowed to perform the requested operation.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Capture the complete error. Record the username, host, database, and operation named in the message. Do not troubleshoot from a shortened log line that omits the host.
  2. Compare the connection identity. If the session opens but a query fails, run SELECT USER(), CURRENT_USER();. If the session cannot open, inspect the exact 'user'@'host' pair printed in the client error from an administrator session.
  3. Inspect effective grants. Run SHOW GRANTS FOR CURRENT_USER; in the failing session, or SHOW GRANTS FOR 'user'@'host'; as an administrator. Look for the needed privilege at the needed object scope.
  4. Check object spelling and scope. Confirm database and table names, including case-sensitive differences on systems where table-name case matters. Compare the grant target, such as appdb.*, with the object the statement actually accesses, such as appdb.orders.
  5. Check roles. SHOW GRANTS can show role assignments, but an assigned role may not be active for the current session. Review the account and session role-activation settings before adding duplicate direct privileges.
  6. Remove accidental breadth. If an earlier troubleshooting attempt granted more than necessary, revoke the unnecessary privilege and issue a least-privilege grant for the correct account.
  7. Retest with the same connection details. Use the same username, host, port, database, and transport settings as the application. Testing with a different client identity can produce a misleading success.

Common causes and the precise correction

The grant was made for the wrong host

Suppose the application error identifies 'appuser'@'127.0.0.1', but the administrator granted privileges to 'appuser'@'localhost'. Those are separate accounts. Either grant the required privileges to the exact authenticated account:

GRANT SELECT, INSERT, UPDATE
ON appdb.*
TO 'appuser'@'127.0.0.1';

or change the client configuration so it connects through the intended host identity. Verify the result with SHOW GRANTS for that same pair. Avoid creating several nearly identical accounts unless each one has a clear operational purpose.

The account exists but has no privileges

A successful CREATE USER followed by a failed query is expected when no GRANT has been issued. Grant the smallest required privilege and verify it:

GRANT SELECT ON appdb.reporting_view TO 'appuser'@'localhost';
SHOW GRANTS FOR 'appuser'@'localhost';

The privilege is granted at the wrong level

A grant on appdb.orders does not authorize a query against appdb.customers. Conversely, a database-level grant may be broader than intended. Match the grant target to the SQL operation and keep the privilege list limited to what the workload performs.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A role is assigned but inactive

Role assignment and role use are distinct. The account can show a role in SHOW GRANTS while the current session still lacks the role’s effective privileges. Check the account’s default-role and session activation configuration, then reconnect or activate the role using your approved role-management procedure. Do not compensate for an activation problem by granting unrelated global privileges.

The failure is authentication, not authorization

A wrong password, incompatible authentication configuration, or an account that does not match the connection host can prevent login before MySQL evaluates the requested statement. In that case, a table grant cannot solve the problem. Confirm that the exact account exists with SHOW CREATE USER, then address the authentication or connection parameters through the supported account statements and client configuration.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Correct accounts without editing system tables

Use supported statements for account administration:

  • CREATE USER to create a new account.
  • ALTER USER to change authentication or account attributes.
  • GRANT to assign privileges or roles.
  • REVOKE to remove privileges or roles.

Do not update the mysql system tables directly. The GRANT documentation warns that altering system-table structure can cause unpredictable login failures. Direct edits also make change history and rollback harder to reason about.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When replacing a credential, coordinate the change with the application’s secret store and connection pool. Test the new credential before retiring the old one, and avoid putting a cleartext password in a command that will be retained in a shared history file.

Password and command-history risks

The MySQL account statements warn that SQL text can be recorded in server logs or in client history such as ~/.mysql_history. A statement containing IDENTIFIED BY 'strong-secret' can therefore expose the password to anyone who can read those files or logs.

  • Use a controlled secret-delivery method rather than pasting production passwords into shared terminals.
  • Restrict access to client history, server logs, backups, and command transcripts.
  • Do not reuse an application password for a human administrator or another service.
  • Remove accidental cleartext copies according to your organization’s retention and incident-response policy.
  • Prefer separate accounts per application or service so a credential can be rotated or revoked without disrupting unrelated workloads.

Worked setup patterns

Local application with read/write access

CREATE USER 'orders_app'@'localhost' IDENTIFIED BY 'unique-secret';
GRANT SELECT, INSERT, UPDATE
ON appdb.orders
TO 'orders_app'@'localhost';
SHOW GRANTS FOR 'orders_app'@'localhost';
SHOW CREATE USER 'orders_app'@'localhost';

This pattern limits the service to one table and three data-manipulation privileges. If the application later needs to create tables or delete rows, treat each requirement as a separate review rather than adding every privilege by default.

Service connecting from one known address

CREATE USER 'billing_app'@'10.20.30.15' IDENTIFIED BY 'unique-secret';
GRANT SELECT, INSERT, UPDATE
ON appdb.*
TO 'billing_app'@'10.20.30.15';

The host restriction is narrower than a wildcard. If the service moves to another address, update the deployment and account plan deliberately; do not immediately replace the restriction with '%' just to restore connectivity.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read-only reporting account

CREATE USER 'report_reader'@'localhost' IDENTIFIED BY 'unique-secret';
GRANT SELECT
ON appdb.*
TO 'report_reader'@'localhost';

A read-only grant prevents the account from inserting, updating, or deleting rows, but database-level visibility still covers every object in appdb. Use a table- or column-level target when reports should see less.

Prevention checklist for deployments

  • Write down the intended user@host identity before creating the account.
  • Create the account separately from granting privileges so the two decisions are visible in change review.
  • Use the smallest practical object scope and privilege list.
  • Run SHOW GRANTS and SHOW CREATE USER after provisioning.
  • Test with the application’s real connection parameters, not an administrator account.
  • Record whether a role is assigned and how it becomes active in a session.
  • Keep passwords out of shared history and logs.
  • Use REVOKE to remove temporary troubleshooting grants after the incident.
  • Never modify MySQL system tables directly.

What to remember

Most permission incidents become straightforward once you keep the identity and authorization checks separate. MySQL authenticates a host-qualified account, then evaluates that account’s active privileges for the requested operation. Create the correct account, grant the narrowest scope, and verify the result with SHOW GRANTS before escalating access.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Access DeniedDatabase administrationleast privilegeMySQLMySQL 8.4SQL permissions

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.