An FTPS certificate mismatch is fixed by the name you dial

Shared hosting FTP certificates usually cover the server node, not ftp.<your-domain>. Read the certificate, connect by the name it covers, and never turn verification off on a session carrying a password.

You connect to ftp.<your-domain> over FTPS. The login works, and then the first directory listing fails:

certificate common name doesn't match requested host name

The usual advice you’ll find is set ssl:verify-certificate no. Please don’t do that on a session that carries a password. Verification is the only thing protecting that password from whoever sits in the middle, and that setting switches it off.

Read the certificate first

The mismatch is telling you something, so look at what the server actually presents:

openssl s_client -connect ftp.<your-domain>:21 -starttls ftp </dev/null \
  | openssl x509 -noout -subject -issuer -dates -ext subjectAltName

On shared hosting you’ll usually get a current, valid certificate whose only name is the hosting node itself, something like cpNNN.<provider>.net, and ftp.<your-domain> turns out to be a CNAME pointing at that node. There’s nothing wrong with the certificate. You’re just dialling it by a name it was never issued for.

Check that both names resolve to the same address, then connect by the node name. Verification passes, you haven’t weakened anything, and it keeps passing after the certificate renews. Use that same name in every deploy script and CI variable that talks to the account. This site’s own pipeline connects that way.

Two lftp habits

Keep the password out of argv. lftp reads ~/.netrc, so running HOME=<scratch-dir> lftp -u <user> <host> with a netrc in the scratch directory keeps the password off the command line and out of the process table. Passwords containing #, $ or @ need no escaping in that file.

Also, dotfiles aren’t listed unless you ask for them. Without set ftp:list-options -a, a mirror silently skips every dot-directory. That includes .well-known/, which on shared hosting is often where the account’s own certificate validation lives, and the mirror still looks complete afterwards.

Checking a mirror against .ftpquota

cPanel-style hosts keep a .ftpquota file in the FTP root. It holds two numbers, inodes and bytes, covering everything in the account except the file itself. So after mirroring the whole account you get an integrity check for free:

find <mirror> | wc -l             # the inode count, plus 1 for .ftpquota
du -sb --apparent-size <mirror>   # roughly the byte count, plus .ftpquota's own size

Directories count as inodes, which is why this uses find without -type f.

If both numbers line up, you have everything. If they don’t, the difference gives you a rough idea of what’s missing, and in my experience it’s usually a dot-directory.

The paths in the account that need protecting are also the ones a safe --delete deploy has to exclude.