DEV Community

Cover image for Upgrading RDS MySQL from 8.0 to 8.4 behind RDS Proxy
gokcedemirdurkut
gokcedemirdurkut

Posted on

Upgrading RDS MySQL from 8.0 to 8.4 behind RDS Proxy

RDS for MySQL 8.0 reaches end of standard support on July 31, 2026 after that AWS moves you onto paid Extended Support until you upgrade, so moving our production databases to 8.4 wasn't really optional. The engine upgrade itself is a non-event: pick the target version, RDS runs its prechecks, takes a snapshot, and a while later you're on 8.4. The part that actually needed thinking was authentication, because all of our services connect through RDS Proxy, and 8.4 changes how the old password plugin works.

If you run the same setup, here's what's worth knowing before you click the button.

The moving parts

If RDS Proxy and MySQL auth plugins are already familiar, skip ahead.

  • Amazon RDS is a managed MySQL database AWS runs the server so you don't have to.
  • RDS Proxy sits in front of it like a hotel front desk. Your applications don't walk up to the room (the database) holding a key; they show ID at the desk, and the desk opens the room for them. It also pools connections so the database isn't swamped.
  • An authentication plugin is just how MySQL checks a password think of it as the type of lock on a door. The old one, mysql_native_password, uses SHA-1 (an older, weaker recipe). The newer caching_sha2_password uses SHA-256 (stronger). MySQL 8.4 stops shipping the old lock by default and expects the new one.

So the whole story below is really: we changed the locks, and the only door that turned out to matter was the one between the front desk and the room.

There are two auth legs, not one

The thing to internalize first: with RDS Proxy in the path, a connection authenticates twice.

  • Service to proxy. Our services don't hold a database password at all. A sidecar mints an IAM auth token and the service uses that to reach the proxy over TLS. This leg is pure IAM the MySQL auth plugin has nothing to do with it.
  • Proxy to database. The proxy then opens the real backend connection using a username/password it pulls from Secrets Manager (one secret per DB user: the app users, a read-only user, the master).

That split matters because the 8.4 authentication change only touches the second leg. Whatever you read about mysql_native_password being disabled applies to how the database authenticates the proxy's connection not to how your services reach the proxy.

The mysql_native_password scare that wasn't

Community MySQL 8.4 doesn't load mysql_native_password by default anymore. Our users including the RDS master user were all created with that plugin, so the obvious worry was: the moment we're on 8.4, the proxy can't authenticate to the backend and everything falls over.

We were ready to flip a parameter to keep the plugin on. Then we actually looked at the 8.4 parameter group:

8.4 parameter group

On RDS for MySQL 8.4, AWS keeps the plugin loaded for you, and you can't turn it off through the parameter group. So existing mysql_native_password users master included keep working after the upgrade with zero changes. The thing we'd braced for simply never happened. The flip side: you can't disable native password on RDS 8.4 either, so a hard "everyone must be caching_sha2" cutover isn't a thing you do here. That only becomes real whenever RDS eventually ships a 9.x line, where the plugin is gone for good.

So the honest answer for an RDS 8.0 → 8.4 upgrade: on the auth front, you don't have to do anything. It keeps working.

Moving to caching_sha2_password anyway

We still moved every user we control to caching_sha2_password not because 8.4 forced us, but because 9.x will. Whenever RDS ships a 9.x line, the native password plugin is gone for good, and a database full of native-password users turns a routine engine bump into an auth scramble at the worst possible time. Doing the migration now, while it's optional and the old plugin is still around as a safety net, means that future upgrade is just a version change. It's also the better plugin on its own merits (SHA-256 instead of SHA-1).

Two preconditions that usually make this annoying were already true for us:

  • RDS Proxy has supported caching_sha2_password since December 2024, and
  • it requires TLS which we already enforce on both the proxy (require_tls) and the instance (require_secure_transport).

So there was no new TLS work to do. All of it lives in Terraform pointing the proxy's client auth at caching_sha2, keeping require_tls on the proxy and require_secure_transport on the instance so the change was a small reviewable diff rather than console clicking. The users themselves we migrate in the small Lambda that initializes the database, using a create-or-migrate pattern:

CREATE USER IF NOT EXISTS `app`@`%` IDENTIFIED WITH caching_sha2_password BY '...';
ALTER USER `app`@`%` IDENTIFIED WITH caching_sha2_password BY '...';
Enter fullscreen mode Exit fullscreen mode

The CREATE ... IF NOT EXISTS handles fresh environments; the ALTER flips the plugin for users that already exist. The order matters: we applied the Terraform first, then triggered that Lambda so the ALTERs actually ran against the live users. It normally only fires once, when the proxy is first created so migrating an already-running environment meant re-running it on purpose. Our services needed no changes for this no driver upgrades, no config, no redeploys. Modern MySQL drivers already speak caching_sha2_password, so the switch was invisible to the applications.

The master user we never touched directly. It's RDS-managed (manage_master_user_password), so RDS rotates its password on a schedule and on 8.4 that managed rotation moved the master onto caching_sha2_password on its own, with no action from us. (Worth knowing: this is RDS's own managed rotation doing it. A plain rotation that runs SET PASSWORD only changes the password and keeps the existing plugin it wouldn't migrate anything.) The only accounts left on native password are the internal ones AWS runs (the RDS admin user, the mysql.* system schemas), and those keep working untouched.

That's why you never have to set a parameter here: RDS keeps mysql_native_password loaded by default for its own accounts, so anything not yet on caching_sha2_password just keeps authenticating.

One catch: Aurora read replicas

If you have an Aurora MySQL read replica hanging off your RDS instance often a leftover from a half-finished move to Aurora it can block the upgrade outright. A replica can't run an older major version than its source, and Aurora MySQL only got an 8.4-compatible version in May 2026, about a year and a half after community 8.4. Until then, moving the RDS source to 8.4 would have broken replication, so the replica quietly vetoes the whole upgrade a big reason some teams stayed on 8.0. The version gap is closed now, but if you run this setup, check the replica side before you touch the source.

In short

The hard part of moving to 8.4 behind RDS Proxy isn't the engine bump it's the auth model, and three things carry most of it. Connections authenticate in two separate legs, and the 8.4 plugin change only touches the proxy-to-database one. RDS keeps mysql_native_password loaded for you, so nothing breaks on its own. And switching to caching_sha2_password costs almost nothing once TLS is already enforced. Get those right and there's very little left to worry about.

Top comments (0)