Skip to main content

Doctor rules

Each rule reads the error, the connection ladder, the detected provider and whether the app runs in a container. Patch fixes are tried against the real target before being offered.

RuleRecognisesProposes
db.tls-requiredMySQL require_secure_transport, caching_sha2_password over plain text, Postgres no pg_hba.conf entry … no encryption, Neon/Supabase "SSL required", or a provider that requires TLSpatch tls: true (then the certificate step); paste the provider CA
db.tls-unsupported"does not support SSL connections", wrong version numberpatch tls: false; enable TLS on the server
tls.untrusted-caself-signed certificate, unable to verify the first certificate / local issuerpaste the CA; patch tlsVerify: false (SQL Server trustServerCertificate, HTTP insecure), lower security
tls.hostname-mismatchcertificate altnames do not matchuse the certificate's hostname
tls.expiredcertificate has expiredrenew on the server
net.dnsENOTFOUND, EAI_AGAIN, missing mongodb+srv record, internal namescheck the name; connect from inside the network
net.localhost-in-containerlocalhost/127.0.0.1 while the app runs in a containerpatch host: host.docker.internal
net.refusedECONNREFUSED, a refused port on the ladderpatch the provider's port (DigitalOcean 25060…); check bind address
net.timeouttimeouts, unreachable hosts, a port that never answersallow this machine's IP; connect from inside the network
auth.rejectedaccess denied, password authentication failed, login failed, Mongo/Atlas bad auth, Redis WRONGPASSre-enter the password; patch authSource: admin (MongoDB)
mysql.host-not-allowedHost 'x' is not allowed to connectthe exact CREATE USER … @'x' and GRANT
db.unknown-databaseunknown database / database does not existpatch database: postgres / master, or none
pg.role-missingrole does not existCREATE ROLE … GRANT pg_monitor
db.too-many-connectionsout of connection slotsthe query that shows who holds them
redis.noauthNOAUTHenter the password
redis.no-password-neededAUTH without a configured passwordpatch: do not send a password
stream.reset-tls-mismatchthe server hangs up right after connecting, TLS offpatch tls: true (possible)
mssql.encryption-requiredserver requires encryptionpatch encrypt: true
aws.no-credentialsno credentials from any providerpaste an access key pair
aws.bad-keyInvalidAccessKeyId, SignatureDoesNotMatch, invalid security tokenre-enter the key pair
aws.region-mismatchwrong region in the authorization header, permanent redirectpatch the expected region
s3.path-stylebucket-subdomain DNS failures on a custom endpointpatch forcePathStyle: true
aws.clock-skewRequestTimeTooSkewedsync the clock (w32tm /resync, timedatectl set-ntp true)
aws.access-deniedAccessDenied, not authorized to performthe exact read-only actions to grant
http.statusan unexpected HTTP statusexplanation by status class; follow redirects; expect the status
ssh.*host key unknown or changed, keys refused, wrong user, unreachable, not SSH on that portplatform-specific steps (trust, ssh-add, ssh-copy-id, the user to use)

When nothing matches, the report still says which rung of the ladder failed, or that the network path works and the service refused for another reason, with the exact error.

Settings a patch may change​

tls, tlsVerify, port, host, authSource, database, region, forcePathStyle, encrypt, trustServerCertificate, insecure, followRedirects, expectStatus, and removing a password reference. Nothing else, ever.

Recognised providers​

DigitalOcean Managed Databases, Amazon RDS, Azure Database / Azure SQL, Supabase, Neon, PlanetScale, Upstash, Amazon ElastiCache, Redis Cloud, MongoDB Atlas and Aiven, with whether they require TLS, their port and where to download their CA.