Beginner 5 min FTP 553

553 File Name Not Allowed — Invalid Characters or Path

Symptoms

- FTP upload fails with "553 Could not create file" or "553 File name not allowed"
- Files with simple alphanumeric names upload successfully; files with spaces, parentheses, or accented characters fail
- Uploading from Windows to a Linux server fails for filenames using backslashes or reserved characters (<, >, :, ", /, \, |, ?, *)
- Server rejects files with specific extensions (.php, .exe, .sh) even if the content is harmless
- Filenames that display correctly in the local file manager appear garbled or rejected on the server due to character encoding differences

Root Causes

  • Filename contains characters that the server's filesystem (ext4, NTFS, FAT32) or the FTP server's filename filter does not permit — common culprits are colons, backslashes, angle brackets, and null bytes
  • Absolute path length exceeds the server's `PATH_MAX` (typically 4096 bytes on Linux) — common with deeply nested directory structures uploaded from Windows
  • FTP server configured with a file extension deny-list (.php, .cgi, .exe, .sh) to prevent uploading executable scripts through the FTP interface
  • Filename encoding mismatch: the client sends UTF-8 bytes while the server expects Latin-1 (ISO-8859-1) — the resulting byte sequence may contain characters the server treats as invalid
  • Leading dot (hidden file such as `.htaccess`) or leading hyphen rejected by the server's security policy or filename validation regex

Diagnosis

**Step 1 — Identify the problematic character**

```bash
# Inspect the raw bytes of the filename:
python3 -c "import sys; print(sys.argv[1].encode('utf-8'))"\
'my file (version 2).zip'
# b'my file (version 2).zip'
# Parentheses are valid on Linux but may be filtered by some FTP servers

# List characters in a filename:
printf '%s' 'my file.txt' | od -An -tx1
```

**Step 2 — Test with a sanitized filename**

```bash
# Rename the file to use only safe characters and retry:
cp 'my file (version 2).zip' my_file_v2.zip
# If the renamed file uploads successfully, the original name is the problem
```

**Step 3 — Check the server's filename deny-list**

```bash
# vsftpd does not have a built-in deny-list, but wrappers may:
grep -r 'deny\|block\|forbidden' /etc/vsftpd/ /etc/proftpd/ 2>/dev/null

# Web hosting panels (cPanel, Plesk) often block executable extensions:
# Check the panel's FTP settings for a file extension filter
```

**Step 4 — Check encoding settings in your FTP client**

```
FileZilla: Edit → Settings → FTP → Use UTF-8
WinSCP: Session → File Protocol settings → Character encoding → UTF-8
```

**Step 5 — Check path length**

```bash
# Measure the full remote path length:
echo -n '/var/ftp/uploads/deeply/nested/path/my_file.zip' | wc -c
# Must be < 4096 bytes on Linux
```

Resolution

**Fix 1 — Sanitize filenames before uploading**

```python
import re

def sanitize_filename(name: str) -> str:
"""Replace characters unsafe for FTP servers."""
# Remove or replace characters outside [A-Za-z0-9._-]
name = re.sub(r'[^\w.\-]', '_', name, flags=re.ASCII)
# Collapse multiple underscores
name = re.sub(r'_{2,}', '_', name)
# Strip leading dots and hyphens
return name.lstrip('.-')

print(sanitize_filename('my file (version 2).zip')) # my_file__version_2_.zip
```

**Fix 2 — Set UTF-8 charset in vsftpd (if encoding mismatch)**

```ini
# /etc/vsftpd.conf
utf8_filesystem=YES
```

```bash
sudo systemctl restart vsftpd
```

**Fix 3 — Allow hidden files (.htaccess) in vsftpd**

```ini
# /etc/vsftpd.conf
# By default vsftpd hides and disallows files starting with '.'
# To allow them:
hide_file={*.secret}
# (leave hide_file unconfigured to allow dotfiles)
```

**Fix 4 — Remove extension block in web hosting panel**

```
cPanel: FTP Accounts → Configure FTP Client → no extension filter by default
Plesk: Tools & Settings → FTP Settings → check 'Forbidden file types' list
```

**Fix 5 — Shorten the remote path**

```bash
# Flatten the directory structure for FTP uploads:
# Instead of /uploads/2026/02/26/photos/vacation/day1/img001.jpg
# Use: /uploads/2026-02-26-vacation-img001.jpg
```

Prevention

- Validate and sanitize filenames in your application before passing them to any FTP client library — restrict to `[A-Za-z0-9._-]` as a safe baseline
- Enforce UTF-8 encoding end-to-end: set `utf8_filesystem=YES` in vsftpd and configure FTP client libraries explicitly rather than relying on system locale defaults
- Document any file extension restrictions enforced by the hosting panel or FTP server so developers know which extensions to avoid before deploying
- Keep remote paths short and flat — avoid deeply nested directory hierarchies in FTP upload workflows that may approach PATH_MAX on some filesystems
- Consider SFTP or object storage (S3, GCS) for file upload pipelines; both support a wider range of character sets and have no filename extension filters

Related Status Codes

Related Terms