Subject: MySQL connection failing with "Access denied" - credentials are correct
ivaldijuancifts19
FREEOP

2 months ago

Description:

I have a Node.js backend service (cards_cloud) trying to connect to a MySQL service in the same Railway project, but getting "Access denied" error despite using correct credentials.

Setup:

  • Backend service: cards_cloud
  • Database: MySQL service in same project
  • Variables in backend: DB_HOST=MySQL.MYSQLHOST,DBPASSWORD={{MySQL.MYSQLHOST}}, DB_PASSWORD= MySQL.MYSQLHOST,DBP​ASSWORD={{MySQL.MYSQLPASSWORD}} etc.

Error in logs:

Access denied for user 'root'@'10.x.x.x' (using password: YES)

What I verified:

  • Credentials match exactly between MySQL variables and backend variables
  • Using internal host: mysql.railway.internal port 3306
  • Also tried with DATABASE_URL=${{MySQL.MYSQL_URL}} — same error
  • Code works perfectly connecting to local MySQL

Question: Is there a known issue with MySQL authentication in Railway? Do I need to configure anything special for internal service-to-service connections?

$10 Bounty

5 Replies

Status changed to Awaiting Railway Response Railway 2 months ago


Status changed to Open ray-chen 2 months ago


goodie323
FREE

2 months ago

Your variable references are malformed — you're using MySQL.MYSQLHOST where the password should be, so your app is literally sending the hostname string as the password.

Fix it to: DB_PASSWORD=${{MySQL.MYSQLPASSWORD}}


elstargo00
PRO

2 months ago

I can see a couple of things in your variable configuration that are very likely causing this.

1. Your DB_PASSWORD appears to reference the wrong variable. In your setup you have:

DB_PASSWORD={{MySQL.MYSQLHOST}}

This is pulling the host value into your password field. It should be:

DB_PASSWORD=${{MySQL.MYSQLPASSWORD}}

2. Your variable reference syntax needs adjustment. Railway's template syntax requires the ${{}} wrapper. Make sure all your references follow this format:

```

DB_HOST=${{MySQL.MYSQLHOST}}

DB_PORT=${{MySQL.MYSQLPORT}}

DB_USER=${{MySQL.MYSQLUSER}}

DB_PASSWORD=${{MySQL.MYSQLPASSWORD}}

DB_NAME=${{MySQL.MYSQLDATABASE}}

```

You can verify the resolved values by checking the Variables tab on your cards_cloud service — Railway shows both the reference and the resolved value. If any of them show as the literal string ${{MySQL.MYSQLHOST}} instead of an actual hostname, the reference isn't resolving.

3. If credentials are confirmed correct, check the MySQL auth plugin. MySQL 8 defaults to caching_sha2_password, which some Node.js MySQL clients don't support. You can fix this by running the following in the Railway MySQL console (via the Data tab):

```

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password';

FLUSH PRIVILEGES;

```

Or, if you're using the mysql2 npm package (recommended over mysql), it supports caching_sha2_password natively.


almastechnology22
FREE

2 months ago

"Hey! I looked into the issue, and it turns out there are a few specific things causing that 'Access denied' error on Railway. It’s not actually a MySQL bug, but more about how the variables are being referenced and how Node.js talks to MySQL 8.

Here’s the fix:

1. Fix the Variable Syntax (The Main Issue)

Railway is very picky about how you reference variables between services. In your setup, you used {{MySQL.VARIABLE}}, but the correct syntax for Railway to actually 'inject' the value is ${{ }}.

Also, looking at your config, you accidentally mapped DB_PASSWORD to MYSQLHOST. You need to update your variables in the cards_cloud service to look exactly like this:

  • DB_HOST: ${{MySQL.MYSQLHOST}}
  • DB_PORT: ${{MySQL.MYSQLPORT}}
  • DB_USER: ${{MySQL.MYSQLUSER}}
  • DB_PASSWORD: ${{MySQL.MYSQLPASSWORD}} <-- Make sure it's not pointing to HOST!
  • DB_NAME: ${{MySQL.MYSQLDATABASE}}

2. Switch to mysql2 Library

The standard mysql package in Node.js doesn't support the new authentication plugin used by MySQL 8 (which Railway uses). If you're using the old library, it’ll give you an 'Access denied' even if the password is correct.

You should swap it for mysql2. It’s a drop-in replacement:

  1. Run: npm uninstall mysql && npm install mysql2
  2. In your code, just change the require: const mysql = require('mysql2');

3. Change the Auth Plugin (Plan B)

If you don't want to change your code, you have to tell MySQL to accept the older password format. Go to the Railway Data/Console tab for your MySQL service and run this:

SQL

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your_actual_password';
FLUSH PRIVILEGES;

Pro tip: Once you update the variables, check the 'Variables' tab in Railway. If you see the actual values (like the real password string) next to the variable name, it means the reference worked. If you still see the ${{...}} text, the syntax is still wrong!"


Anonymous
HOBBY

2 months ago

This looks like an environment variable mapping issue rather than a Railway bug.

Make sure you're using Railway's provided variables correctly:

  • MYSQLHOST
  • MYSQLUSER
  • MYSQLPASSWORD
  • MYSQLDATABASE

Instead of manually assigning values, try:

DATABASE_URL=${{MySQL.MYSQL_URL}}

Also ensure you're not hardcoding root as the user — Railway may restrict it.

Since your app works locally, the issue is likely due to incorrect variable references (e.g., using MYSQLHOST as password).

Try cleaning up duplicate/incorrect env vars and redeploying.


papaya-voldemort
HOBBY

2 months ago

Because you are getting "Access denied" it means your backend is reaching the database, but your password variable is broken.

Looking at your setup, you have a few typos in your variables:

  • Missing $: In Railway, I think you need ${{ }} to reference other services. You wrote {{MySQL.MYSQLPASSWORD}} without the $.
  • Wrong Variable: You have DB_PASSWORD set it to MySQL.MYSQLHOST. That's sending the hostname as your password, which is not right
  • Spaces**:** Make sure there isn't a space after the = (like in your DB_PASSWORD= MySQL... example). Or anywhere elese in the variables

Try setting your backend variables to something like this:

  • DB_HOST: ${{MySQL.MYSQL_HOST}}
  • DB_PASSWORD: ${{MySQL.MYSQL_PASSWORD}}
  • DB_USER: root

That might fix the authentication error but I am still pretty new to this :)


Welcome!

Sign in to your Railway account to join the conversation.

Loading...