MySQL TLS and encryption monitoring: unencrypted connections and weak auth plugins
MySQL 8.0 generates self-signed certificates on startup and enables TLS by default, but this does not guarantee encrypted traffic. Clients must explicitly request TLS over TCP, and misconfigurations often leave sessions in plaintext without errors. Long-lived accounts frequently remain on mysql_native_password despite its deprecation in MySQL 8.0.34, while caching_sha2_password requires secure transport or RSA key exchange on first connection, causing sporadic authentication failures when client drivers lack encryption configuration. These risks are invisible to standard availability monitoring. This guide covers the status variables, Performance Schema tables, and account audits needed to detect unencrypted connections and weak authentication plugins in production.
flowchart TD
A[Client connection] --> B{require_secure_transport}
B -->|ON| C{Secure transport}
B -->|OFF| D[Allowed: check encryption]
C -->|No| E[Reject: Error 3159]
C -->|Yes| F[Allowed: check plugin]
D --> G{Account REQUIRE SSL}
G -->|Yes and no TLS| H[Reject]
G -->|No or TLS| F
F -->|caching_sha2_password| I{First connect}
I -->|No TLS/RSA| J[Auth failure]
I -->|TLS or cached| K[Authenticated]
F -->|mysql_native_password| L[Deprecated: audit]What invisible exposure looks like
Unencrypted MySQL traffic usually produces no application errors: connections succeed, queries execute, and metrics look healthy. Exposure only becomes visible when you inspect the transport layer or audit account configuration.
- Silent plaintext sessions: The server reports
have_ssl = YES, but application connection strings omit TLS flags. Inperformance_schema.threads, TCP connections showCONNECTION_TYPE = 'TCP/IP'instead of'SSL/TLS'. Health checks that open TCP, sendSELECT 1, and close without negotiating TLS inflate the unencrypted connection count without carrying sensitive data, but application queries carrying credentials or user data over the same channel create real exposure. - Deprecated plugin persistence: Accounts created before an upgrade to MySQL 8.0 retain
mysql_native_password. The server emits warning[MY-013360]to the error log on each use, but these warnings are often lost in log noise. - First-connect caching_sha2_password failures: After a password rotation, an application’s first connection attempt fails because the client driver lacks TLS or RSA configuration. The second attempt succeeds because the credential is now cached, making the failure transient and hard to reproduce.
- Secure transport mismatches: An account with
REQUIRE SSLrejects Unix socket connections even though sockets are treated as secure by the server-siderequire_secure_transportlogic. This breaks local admin tools and containerized applications that rely on socket connections.
TLS connection signals to monitor
Global TLS counters and context
Do not rely on have_ssl alone. It indicates the server was built with SSL support and certificates are available, but does not prove clients are using them.
Ssl_accepts: Cumulative accepted SSL connections. Compare its growth to total new connections. IfSsl_acceptsis flat while connection volume grows, traffic is likely falling back to plaintext.Ssl_finished_acceptsandSsl_finished_connects: Successful SSL connections to the server and from the server to replication sources, respectively.Tls_library_version: Reports the linked OpenSSL version. Confirms TLSv1.3 eligibility, which requires OpenSSL 1.1.1 or newer.
MySQL 8.0 also exposes current_tls_version, current_tls_cipher, and related current_tls_* status variables. These reflect the active TLS context after the last ALTER INSTANCE RELOAD TLS, not the static system variable values. If a runtime reload fails or the server falls back to compiled-in defaults, the current_tls_* values reveal the effective configuration.
Per-connection transport verification
To inspect active connections individually, query performance_schema.threads:
SELECT PROCESSLIST_USER,
PROCESSLIST_HOST,
CONNECTION_TYPE
FROM performance_schema.threads
WHERE TYPE = 'FOREGROUND';
CONNECTION_TYPE returns SSL/TLS, TCP/IP, or Unix socket. Any production TCP connection showing TCP/IP instead of SSL/TLS is a candidate for remediation.
For the current session, SHOW SESSION STATUS LIKE 'Ssl_version' returns an empty string when encryption is not in use. The same applies to Ssl_cipher. These are useful for ad-hoc verification from application client hosts.
Structured channel status
performance_schema.tls_channel_status (available since MySQL 8.0.21) provides a structured view of TLS properties per channel, such as mysql_main and mysql_admin. The PROPERTIES column includes the active protocol version and cipher suite, making it easier to parse than legacy global status variables. Query this table after rotating certificates or reloading TLS at runtime to confirm the new context took effect without requiring a restart.
Authentication plugin audit
Detecting deprecated and weak plugins
Inventory all accounts and their authentication plugins:
SELECT user, host, plugin, ssl_type
FROM mysql.user
WHERE user != '';
Flag any account using mysql_native_password. This plugin is deprecated as of MySQL 8.0.34. The server writes warning [MY-013360] to the error log on each connection that uses it. Oracle has not announced a specific removal version, but the deprecation signals approaching end-of-life.
For environments using roles, remember that role assignments do not change the underlying account plugin. Audit the base user accounts, not just active roles.
caching_sha2_password first-connect requirements
caching_sha2_password is the default authentication plugin in MySQL 8.0. The first connection after account creation or a password change must occur over a secure transport (TLS, Unix socket, or shared memory) or use RSA key-pair password exchange. After the first successful connection, the credential is cached and subsequent connections may succeed even without TLS.
This creates a specific failure signature: after credential rotation, applications that were previously working suddenly produce authentication errors on the first connection attempt, then recover on retry. If you see a spike in Aborted_connects correlated with a password change event but no corresponding persistent outage, check whether the client driver is configured to use TLS or whether the server has been configured with an RSA public key for the plugin.
If the client cannot use TLS and the server has not been configured for RSA key exchange, the authentication fails with an access-denied error. The error is transient from the application’s perspective because once any client successfully caches the credential, subsequent connections from that host may succeed depending on the driver’s caching behavior. This makes the failure appear random during connection pool churn or after failover events.
Account-level SSL requirements
Individual accounts can enforce TLS with REQUIRE SSL. However, REQUIRE SSL demands an SSL connection specifically. It rejects Unix socket and shared memory connections even though those transports are considered secure by the server-side require_secure_transport logic. Before applying REQUIRE SSL broadly, confirm that local tools and sidecar containers do not rely on socket connections.
Server configuration and enforcement checks
require_secure_transport
Setting require_secure_transport = ON causes MySQL to reject any connection that does not use a secure transport. The client receives error 3159 (Connections using insecure transport are prohibited). This is effective lockdown, but a blunt instrument. Before enabling it globally, verify that:
- All application connection strings explicitly enable TLS or use Unix sockets.
- All replicas using TCP are configured with
SOURCE_SSL=1(orMASTER_SSL=1on older versions). Otherwise the replication I/O thread connects over plaintext TCP and is rejected immediately, breaking replication with error 3159 in the replica’s error log. - Monitoring and backup tools that connect over TCP support TLS.
tls_version and cipher configuration
tls_version controls which protocols the server permits. In MySQL 8.4 and later, the default is TLSv1.2,TLSv1.3; TLSv1 and TLSv1.1 were removed in MySQL 8.0.
Incorrect cipher configuration can disable encrypted connections entirely. Verify that have_ssl remains YES after any cipher changes.
Certificate expiry
Certificate expiry is a silent failure. The server continues running, but new TLS connections fail when clients enforce validity dates. This manifests as a sudden application-side connection storm while MySQL continues to accept TCP connections. Monitor the certificate files referenced by your TLS configuration. The current_tls_* global status variables show the active certificate paths, which helps confirm which files to check on disk. Schedule file-system validation of those PEM files as part of certificate lifecycle management.
Signals to monitor summary
| Signal | Source | Why it matters | Warning sign |
|---|---|---|---|
Ssl_accepts | SHOW GLOBAL STATUS | Tracks accepted SSL handshakes | Flat or slow growth while total connections increase |
CONNECTION_TYPE | performance_schema.threads | Shows whether a session uses TCP, SSL, or socket | Active TCP entries without SSL/TLS |
Ssl_version (session) | SHOW SESSION STATUS | Empty string means unencrypted | Empty value on TCP client connections |
current_tls_version | SHOW GLOBAL STATUS | Effective TLS protocol in use | Protocol older than site policy |
Tls_library_version | SHOW GLOBAL STATUS | Linked OpenSSL version | OpenSSL too old for TLSv1.3 |
mysql_native_password accounts | mysql.user | Deprecated plugin | Any production account still using it |
caching_sha2_password first-connect failures | Error log + Aborted_connects | Requires TLS or RSA on first connection | Sporadic auth failures after credential rotation |
require_secure_transport | SHOW GLOBAL VARIABLES | Global enforcement switch | Unexpected error 3159 spikes after enablement |
| Certificate validity | File system / current_tls_* | Expired certs break new TLS connections | Expiration within planned rotation window |
How Netdata helps
- Correlate encryption adoption with connection health: Netdata tracks
Ssl_acceptsand total connection rates. A widening gap between total connections and SSL accepts signals plaintext leakage that standard health checks miss. - Link auth failures to TLS context changes: Correlate spikes in
Aborted_connectswith certificate rotation events orALTER INSTANCE RELOAD TLSoperations. This distinguishescaching_sha2_passwordfirst-connect failures from brute-force attacks. - Audit plugin distribution: Use Netdata’s custom query monitoring to run periodic audits of
mysql.userplugin assignments and alert on any account usingmysql_native_password. - Track TLS version drift: Monitor
current_tls_versionandTls_library_versionto detect configuration regressions or hosts running outdated OpenSSL builds.
Related guides
- How MySQL actually works in production: a mental model for operators: /guides/mysql/how-mysql-works-in-production/
- MySQL Aborted_connects and Aborted_clients climbing: diagnosis: /guides/mysql/mysql-aborted-connections/
- MySQL ERROR 1045 (28000): Access denied for user - diagnosis: /guides/mysql/mysql-access-denied-for-user/
- MySQL adaptive hash index latch contention: high CPU, low throughput: /guides/mysql/mysql-adaptive-hash-index-latch-contention/
- MySQL authentication failure spike: brute force vs broken credential rotation: /guides/mysql/mysql-auth-failure-rate/
- MySQL binary logs filling the disk: expiry, lagging replicas, and purge: /guides/mysql/mysql-binary-log-disk-full/
- MySQL InnoDB buffer pool hit ratio collapse: the cliff edge: /guides/mysql/mysql-buffer-pool-hit-ratio-collapse/
- MySQL slow after restart: buffer pool warm-up and the cold cache: /guides/mysql/mysql-buffer-pool-not-warming-up/
- MySQL innodb_buffer_pool_size tuning: 60-80% of RAM and when that breaks: /guides/mysql/mysql-buffer-pool-sizing/
- MySQL Innodb_buffer_pool_wait_free > 0: buffer pool memory pressure: /guides/mysql/mysql-buffer-pool-wait-free/
- MySQL InnoDB checkpoint age: the redo log capacity signal nobody watches: /guides/mysql/mysql-checkpoint-age-monitoring/
- MySQL connection exhaustion: detection, diagnosis, and prevention: /guides/mysql/mysql-connection-exhaustion/







