Skip to main content

Fixed: "Failed to read file at the specified location" with MySql.Data

· 5 min read
Jagdish Kumawat
Founder @ Dewiride

Failed to read file at the specified location is the driver saying it can't open the file you named. The same relative path worked in one terminal and failed in another, because a relative path depends on the folder the app starts in, and that isn't always the folder you're in.

What I Was Doing​

I was using SslCa=certs/ca.pem, relative to my project folder, on MySql.Data 26.10.0 and .NET 10:

Connection string
…;SslMode=VerifyCA;SslCa=certs/ca.pem

From the folder holding certs/, it connected. Then I ran the same program from another folder:

Terminal
cd /tmp
dotnet run /Users/you/projects/mysql-connection-test/test-connection.cs

What I Expected​

The same connection, because I hadn't changed the connection string.

What I Got​

Output
Unhandled exception. MySql.Data.MySqlClient.MySqlException (0x80004005): SSL Connection error
---> System.IO.FileNotFoundException: Failed to read file at the specified location
File name: 'certs/ca.pem'

The test program stopping with SSL Connection error and Failed to read file at the specified location, with File name: certs/ca.pem.

What I Checked​

The File name: line. It's the path as the driver saw it, and here it's relative. So the path depends on the process's working folder.

Where an ASP.NET Core app starts. With dotnet run --project src/Dewiride.Inventory.Api from the solution folder, the same SslCa=certs/ca.pem also failed. The app's log says why:

API log
info: Microsoft.Hosting.Lifetime[0]
Content root path: /Users/you/projects/dewiride-inventory-api/src/Dewiride.Inventory.Api

dotnet run --project starts the app in the project's folder, so certs/ca.pem meant a folder that doesn't exist.

A file that isn't there at all. Same message, with the full path in the File name: line:

Output
Unhandled exception. MySql.Data.MySqlClient.MySqlException (0x80004005): SSL Connection error
---> System.IO.FileNotFoundException: Failed to read file at the specified location
File name: '/Users/you/projects/mysql-connection-test/certs/nope.pem'

Why It Happens​

The driver opens the path as it stands, and the operating system resolves a relative path from the process's working folder. That folder changes with how you start the app: from a terminal, with dotnet run --project, from Visual Studio, or under a service.

The Fix​

Use a full path. When you set the string from a terminal, the shell can fill it in for you, in bash, zsh and PowerShell alike:

Connection string, in a double-quoted command
…;SslMode=VerifyCA;SslCa=$PWD/certs/ca.pem

For example, $PWD here becomes your current folder:

Terminal
export MYSQL_CONNECTION_STRING="Server=127.0.0.1;Port=3306;Database=inventory;User ID=inventory_app;Password=$(grep '^MYSQL_PASSWORD=' ../dewiride-inventory-api/.env | cut -d= -f2-);SslMode=VerifyCA;SslCa=$PWD/certs/ca.pem"

On a server, set the full path in the environment variable that holds the connection string.

If the file really is missing, the File name: line tells you where the driver looked. Copy the file there, or fix the path.

After the Fix​

Terminal
dotnet run test-connection.cs
Output
Connected as inventory_app@% to MySQL 9.7.4
TLS: TLSv1.2

The test program printing Connected as inventory_app@% with TLS: TLSv1.2, with a full path in SslCa.

Common Mistakes​

MistakeWhat happensDo this instead
A relative path in an app you start with --projectIt's resolved from the project's folderUse a full path
~/certs/ca.pemThe driver takes ~ literally, and gives this errorLet the shell fill it in, with $HOME
A file the app's account can't readThe same message, even though the file is thereCheck the file's permissions

Troubleshooting​

SymptomLikely causeFix
No file path has been providedThe option isn't set at allThe fix
The specified file cannot be converted to a keyIt found the file, and can't read the formatThe fix
It works locally, and fails on a serverThe file isn't deployed thereMount it, and use that path

Conclusion​

The File name: line in this error shows the path the driver tried. Use a full path, so it doesn't depend on where the app starts.

Additional Resources​

Stay Updated

Subscribe to our newsletter for the latest tutorials, tech insights, and developer news.

By subscribing, you agree to our privacy policy. Unsubscribe at any time.