550 File Unavailable — Permission Denied
लक्षण
- FTP upload fails with "550 Permission denied" or "550 Failed to open file"
- Directory listing (LIST) succeeds but STOR (upload) or RETR (download) is rejected
- Creating a new directory fails with 550 even though the parent directory is visible
- Error is specific to certain directories — other paths work normally
- The FTP user can log in successfully but cannot modify any files on the server
- Directory listing (LIST) succeeds but STOR (upload) or RETR (download) is rejected
- Creating a new directory fails with 550 even though the parent directory is visible
- Error is specific to certain directories — other paths work normally
- The FTP user can log in successfully but cannot modify any files on the server
मूल कारण
- Unix filesystem permissions (chmod/chown) do not grant the FTP daemon's system user read or write access to the target directory
- The FTP user's home directory is owned by root (common after `useradd` without `-m`) rather than the FTP user — vsftpd requires the home to be non-writable by the user when `chroot_local_user=YES`
- SELinux is enforcing and the `ftp_home_dir` or `allow_ftpd_full_access` boolean is set to off, blocking the FTP daemon from writing to allowed paths
- The FTP server's chroot jail prevents the user from accessing paths outside the jail, and the upload target is outside the configured home directory
- Disk quota for the FTP user account is exhausted — the server accepts the connection and the STOR command but rejects the write with 550
निदान
**Step 1 — Check filesystem ownership and permissions**
```bash
# From the server shell:
ls -la /var/ftp/uploads/
# Look for the owner and permission bits:
# drwxr-xr-x root root → FTP user cannot write
# drwxrwxr-x ftpuser ftpuser → FTP user can write
```
**Step 2 — Identify the FTP daemon's system user**
```bash
# vsftpd runs file I/O as the authenticated user's system account
grep '^nopriv_user' /etc/vsftpd.conf # default: nobody
# For virtual users, check guest_username:
grep '^guest_username' /etc/vsftpd.conf
```
**Step 3 — Check SELinux booleans (RHEL/CentOS/AlmaLinux)**
```bash
getsebool -a | grep ftp
# Common booleans:
# ftp_home_dir --> off (must be on to write to home dirs)
# allow_ftpd_anon_write --> off
# allow_ftpd_full_access --> off
# Test: temporarily put SELinux in permissive mode
sudo setenforce 0
# If FTP now works, SELinux is the cause
```
**Step 4 — Check disk quota**
```bash
quota -u ftpuser
# Or check overall disk usage:
df -h /var/ftp/
```
**Step 5 — Check vsftpd chroot configuration**
```bash
grep -E 'chroot|local_root|user_sub_token' /etc/vsftpd.conf
```
```bash
# From the server shell:
ls -la /var/ftp/uploads/
# Look for the owner and permission bits:
# drwxr-xr-x root root → FTP user cannot write
# drwxrwxr-x ftpuser ftpuser → FTP user can write
```
**Step 2 — Identify the FTP daemon's system user**
```bash
# vsftpd runs file I/O as the authenticated user's system account
grep '^nopriv_user' /etc/vsftpd.conf # default: nobody
# For virtual users, check guest_username:
grep '^guest_username' /etc/vsftpd.conf
```
**Step 3 — Check SELinux booleans (RHEL/CentOS/AlmaLinux)**
```bash
getsebool -a | grep ftp
# Common booleans:
# ftp_home_dir --> off (must be on to write to home dirs)
# allow_ftpd_anon_write --> off
# allow_ftpd_full_access --> off
# Test: temporarily put SELinux in permissive mode
sudo setenforce 0
# If FTP now works, SELinux is the cause
```
**Step 4 — Check disk quota**
```bash
quota -u ftpuser
# Or check overall disk usage:
df -h /var/ftp/
```
**Step 5 — Check vsftpd chroot configuration**
```bash
grep -E 'chroot|local_root|user_sub_token' /etc/vsftpd.conf
```
समाधान
**Fix 1 — Correct filesystem ownership and permissions**
```bash
# Give the FTP user ownership of the upload directory:
sudo chown ftpuser:ftpuser /var/ftp/uploads
sudo chmod 755 /var/ftp/uploads
# For anonymous FTP uploads, the directory must be writable by ftp:
sudo chown ftp:ftp /var/ftp/pub/upload
sudo chmod 730 /var/ftp/pub/upload
```
**Fix 2 — Fix vsftpd chroot home directory ownership**
```bash
# vsftpd chroot_local_user=YES requires the home dir to be owned by root
# and NOT writable by the user; uploads go into a subdirectory:
sudo chown root:root /home/ftpuser
sudo chmod 755 /home/ftpuser
sudo mkdir -p /home/ftpuser/uploads
sudo chown ftpuser:ftpuser /home/ftpuser/uploads
```
**Fix 3 — Enable SELinux FTP booleans**
```bash
# Allow FTP write access to home directories:
sudo setsebool -P ftp_home_dir on
# Allow FTP full filesystem access (less restrictive):
sudo setsebool -P allow_ftpd_full_access on
# Apply the correct SELinux context to a custom directory:
sudo semanage fcontext -a -t public_content_rw_t '/srv/ftp(/.*)?'
sudo restorecon -Rv /srv/ftp/
```
**Fix 4 — Expand or remove the disk quota**
```bash
# Increase soft/hard quota for the user (ext4 quota):
sudo edquota -u ftpuser
# Or remove quota limits entirely:
sudo setquota -u ftpuser 0 0 0 0 /
```
```bash
# Give the FTP user ownership of the upload directory:
sudo chown ftpuser:ftpuser /var/ftp/uploads
sudo chmod 755 /var/ftp/uploads
# For anonymous FTP uploads, the directory must be writable by ftp:
sudo chown ftp:ftp /var/ftp/pub/upload
sudo chmod 730 /var/ftp/pub/upload
```
**Fix 2 — Fix vsftpd chroot home directory ownership**
```bash
# vsftpd chroot_local_user=YES requires the home dir to be owned by root
# and NOT writable by the user; uploads go into a subdirectory:
sudo chown root:root /home/ftpuser
sudo chmod 755 /home/ftpuser
sudo mkdir -p /home/ftpuser/uploads
sudo chown ftpuser:ftpuser /home/ftpuser/uploads
```
**Fix 3 — Enable SELinux FTP booleans**
```bash
# Allow FTP write access to home directories:
sudo setsebool -P ftp_home_dir on
# Allow FTP full filesystem access (less restrictive):
sudo setsebool -P allow_ftpd_full_access on
# Apply the correct SELinux context to a custom directory:
sudo semanage fcontext -a -t public_content_rw_t '/srv/ftp(/.*)?'
sudo restorecon -Rv /srv/ftp/
```
**Fix 4 — Expand or remove the disk quota**
```bash
# Increase soft/hard quota for the user (ext4 quota):
sudo edquota -u ftpuser
# Or remove quota limits entirely:
sudo setquota -u ftpuser 0 0 0 0 /
```
रोकथाम
- Provision FTP home directories with a standard script that sets correct ownership and permissions from the start, avoiding manual chmod mistakes
- On SELinux systems, apply the correct file context to FTP directories (`public_content_rw_t`) immediately when creating them — do not disable SELinux
- Set disk quotas with generous limits and alert at 80% usage rather than letting them silently cause 550 errors during file transfers
- Test FTP access after every system update or OS upgrade — package updates occasionally reset SELinux booleans or change daemon user accounts
- Migrate to SFTP (SSH) where possible; it inherits the SSH user's standard Unix permissions without requiring additional FTP-specific configuration
- On SELinux systems, apply the correct file context to FTP directories (`public_content_rw_t`) immediately when creating them — do not disable SELinux
- Set disk quotas with generous limits and alert at 80% usage rather than letting them silently cause 550 errors during file transfers
- Test FTP access after every system update or OS upgrade — package updates occasionally reset SELinux booleans or change daemon user accounts
- Migrate to SFTP (SSH) where possible; it inherits the SSH user's standard Unix permissions without requiring additional FTP-specific configuration