🚀   Portable does more than just ELT. Explore Our AI Orchestration Capabilities 

Troubleshooting TLS/SSL Errors

Sergio
CTO

When connecting to your database with SSL/TLS enabled, Portable attempts to establish a secure, encrypted connection. If this step fails, you'll see a "TLS Handshake" error in the diagnostic checks.

What This Means

Portable can reach your database server, but the TLS/SSL negotiation failed. This could be due to certificate issues, configuration mismatches, or the server not supporting SSL.

How Portable Handles TLS/SSL

Portable uses a certificate verification mode similar to PostgreSQL's sslmode=verify-ca:

  • The server's certificate is validated against the CA certificate you provide
  • Hostname verification is not performed (this allows connections to servers behind load balancers or proxies)
  • All certificates must be in PEM format

Supported SSL Options

FieldDescription
SSL Server CAThe Certificate Authority's public certificate used to verify the server's certificate
SSL Client CertificateYour client's public certificate (for mutual TLS / client certificate authentication)
SSL Client KeyYour client's private key (paired with the client certificate)

Common Causes

1. Server Doesn't Support SSL

Your database server may not have SSL enabled.

How to check:

For PostgreSQL:

SHOW ssl;
-- Should return 'on'

For MySQL:

SHOW VARIABLES LIKE 'have_ssl';
-- Should return 'YES'

2. Wrong or Missing CA Certificate

If you provide an SSL Server CA, it must be the certificate that signed your database server's certificate.

Common mistakes:

  • Using the server's certificate instead of the CA certificate
  • Using an expired CA certificate
  • Using a CA certificate from a different certificate chain

To verify your CA certificate matches:

# Download server certificate
openssl s_client -connect db.example.com:5432 -starttls postgres </dev/null 2>/dev/null | openssl x509 -outform PEM > server.crt

# Verify against your CA
openssl verify -CAfile your_ca.pem server.crt
# Should output: server.crt: OK

3. Certificate Format Issues

All certificates and keys must be in PEM format.

Valid PEM format looks like:

-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvg...
-----END CERTIFICATE-----

For private keys:

-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA...
-----END RSA PRIVATE KEY-----

or

-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBg...
-----END PRIVATE KEY-----

If your certificate is in DER format, convert it:

openssl x509 -inform DER -in cert.der -out cert.pem

4. Client Certificate Issues (Mutual TLS)

If your database requires client certificate authentication, both the certificate and private key must be provided and must match.

To verify your client cert and key match:

# Check the modulus of the certificate
openssl x509 -noout -modulus -in client.crt | openssl md5

# Check the modulus of the key
openssl rsa -noout -modulus -in client.key | openssl md5

# These should produce the same hash

Common issues:

  • Providing only the certificate without the key (or vice versa)
  • Certificate and key don't match (from different key pairs)
  • Private key is encrypted with a passphrase (must be decrypted)

To remove passphrase from a key:

openssl rsa -in encrypted.key -out decrypted.key

5. Expired Certificates

Certificates have validity periods. An expired CA or server certificate will cause the handshake to fail.

To check certificate expiration:

openssl x509 -in your_cert.pem -noout -dates

6. Self-Signed Certificates

If your database uses a self-signed certificate, you must provide that certificate as the SSL Server CA. The server's certificate acts as its own CA in this case.

Database-Specific Notes

PostgreSQL

PostgreSQL uses the ssl parameter and related settings in postgresql.conf:

ssl = on
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
ssl_ca_file = 'ca.crt'  # For client cert verification

MySQL

MySQL requires SSL settings in my.cnf:

[mysqld]
ssl-ca=/path/to/ca.pem
ssl-cert=/path/to/server-cert.pem
ssl-key=/path/to/server-key.pem
require_secure_transport=ON  # To force SSL

Cloud-Specific Instructions

AWS RDS

AWS RDS uses certificates signed by the RDS Certificate Authority:

  1. Download the RDS CA bundle from AWS documentation
  2. Use the appropriate regional or global root CA as your SSL Server CA
  3. Client certificates are not supported on RDS

Google Cloud SQL

Cloud SQL uses Google-managed certificates:

  1. In Cloud Console, go to Cloud SQL → Your Instance → Connections → Security
  2. Download the server CA certificate
  3. For client certificates, create them in the console and download both cert and key

Azure Database

Azure uses DigiCert-signed certificates:

  1. Download the root CA from Azure documentation
  2. Client certificate authentication is not supported on most Azure database services

How to Diagnose

Test SSL connection with openssl

# PostgreSQL (uses STARTTLS)
openssl s_client -connect db.example.com:5432 -starttls postgres

# MySQL (uses STARTTLS)
openssl s_client -connect db.example.com:3306 -starttls mysql

# Direct SSL (port 443 or similar)
openssl s_client -connect db.example.com:443

Look for:

  • Verify return code: 0 (ok) - certificate chain is valid
  • Verify return code: 19 (self signed certificate in certificate chain) - need to provide the CA
  • Verify return code: 10 (certificate has expired) - certificate needs renewal

Test with database client

# PostgreSQL with SSL
psql "host=db.example.com dbname=mydb user=myuser sslmode=verify-ca sslrootcert=ca.pem"

# MySQL with SSL
mysql -h db.example.com -u myuser -p --ssl-ca=ca.pem --ssl-mode=VERIFY_CA

Checklist

Before contacting support, verify:

  • Database server has SSL enabled
  • SSL Server CA is in PEM format (starts with -----BEGIN CERTIFICATE-----)
  • CA certificate matches the one that signed the server's certificate
  • Certificates are not expired
  • If using client certs: both certificate and key are provided
  • If using client certs: certificate and key match (same key pair)
  • Private key has no passphrase

Still Stuck?

If SSL works with command-line tools but Portable still reports a TLS error, contact support with:

  • Your database type (PostgreSQL, MySQL)
  • Whether you're using a cloud provider (AWS RDS, Cloud SQL, Azure)
  • The output of openssl s_client -connect <host>:<port>
  • Whether you're using client certificate authentication
  • Your source/destination ID from Portable