How-to

Why hidden files don't show up on an FTP server

4 min read

You need to edit .htaccess, or check a .env, or find out why .well-known is not being served. You connect over FTP, you turn on “show hidden files”, and the folder still looks empty. The file is definitely there — you can see it over SSH.

This is not your client being broken, and it is not a permissions problem. It is how the FTP protocol lists directories.

LIST does not show dotfiles

When an FTP client shows you a folder it sends the LIST command, and the server answers with something that looks like the output of ls -l. And like ls, plain LIST does not include entries starting with a dot.

LIST /var/www/html
(empty)

LIST -a /var/www/html
-rw-r--r--  1 www  www   372 Jul 21 12:11 .htaccess

So the client never receives .htaccess at all. A “show hidden files” toggle that filters the received list — which is what most clients implement — has nothing to filter: the entry never arrived.

LIST -a, and why it is not the default

Most servers accept an argument after LIST and pass it to the underlying listing, so LIST -a returns dotfiles as well. It is not part of the FTP standard — RFC 959 says the argument is a pathname — which is why clients cannot simply always use it: a minority of servers interpret -a as a file name and answer with an error or an empty listing.

A well-behaved client tries LIST -a and falls back to plain LIST if the server refuses, so you get hidden files where they are available and a working listing everywhere else.

MLSD: the modern answer

Newer servers advertise MLSD, a machine-readable listing defined in RFC 3659. It returns every entry, dotfiles included, with typed facts instead of a human-formatted line — no guessing about date formats or column positions:

type=file;size=372;modify=20260721121100; .htaccess
type=dir;size=4096;modify=20260718090300; uploads

You can check what your server supports by looking at its FEAT response. If MLSD appears there, listings are both complete and unambiguous. If it does not, you are in LIST territory and the -a question applies.

Why it matters more than it sounds

Invisible dotfiles are not just an annoyance. Folder synchronisation that relies on listings will not see them either: sync a local folder to the server and .htaccess is neither uploaded nor compared — silently. Mirror mode will not delete it either, so the two sides quietly diverge.

If you have ever synced a site and wondered why the rewrite rules on the server were stale, this is a strong candidate.

What about SFTP?

SFTP has none of this. Its directory listing is a structured protocol operation that returns every entry, so hidden files are always present and it is up to the client to show or hide them. If you have the choice, SFTP is the less surprising protocol — and the encrypted one.

How Upstream handles it

Upstream uses MLSD when the server advertises it, and LIST -a otherwise, falling back to plain LIST if the server rejects the argument. Hidden files are then shown or hidden by the View ▸ Show Hidden Files setting, and folder sync sees them too.

This was a real bug in Upstream until version 1.1: the toggle filtered a listing that never contained dotfiles, so on FTP it appeared to do nothing at all.

Step by step

  1. Check whether your server supports MLSD — look at the FEAT response in your client’s protocol log. If MLSD is listed, listings already include hidden files.
  2. Make sure the client asks for hidden entries — on LIST-only servers the client has to send LIST -a. In Upstream this happens automatically, with a fallback to plain LIST for servers that reject it.
  3. Turn on Show Hidden Files — in Upstream: View ▸ Show Hidden Files (⇧⌘.). The setting applies to both panes.
  4. Prefer SFTP where you can — if the server offers SSH, use SFTP: listings always contain every entry, and the connection is encrypted.

Questions people ask

Why does my client’s “show hidden files” toggle do nothing?

Because on FTP it filters a list that never contained the hidden entries. The fix has to happen one level down, in how the client asks the server for the listing.

Is LIST -a safe to send to any server?

Almost always, but not universally: a few servers treat -a as a pathname and return an error or an empty folder. That is why a client should fall back to plain LIST rather than assume.

Does this affect uploads too?

No. You can upload, download, rename and delete a dotfile perfectly well over FTP — you just cannot see it in a plain listing. Anything driven by a listing, like sync, is affected.

Do I need special permissions to see .htaccess?

No. If you can read the directory you can see its dotfiles; the protocol just has to be asked for them.

Upstream — the native FTP, FTPS & SFTP client for macOS

A transfer queue you can pause, resume and reorder, folder synchronization with a dry-run preview, live remote editing and credentials in the macOS Keychain. Free to download, no subscription.