/etc/fstab (filesystem table) tells a Linux system which filesystems to mount at boot, where to mount them and with which options. On modern distributions systemd reads it at boot and turns each line into a mount unit. This guide explains the format, shows correct entries for the most common cases (local disks, swap files, bind mounts, tmpfs, NFS and SMB shares) and gives you a safe procedure to add entries without ending up with a server that does not boot. Commands are shown for Ubuntu 24.04 and work the same on Debian 12 and Rocky Linux 9.

Prerequisites

  • A Linux server running Ubuntu 24.04 LTS or another systemd-based distribution, for example a CubePath VPS.
  • A non-root user with sudo privileges.
  • Access to your provider's web console. If a bad fstab entry stops the boot, SSH will not be available and the console is how you fix it.

Understanding the fstab format

Look at the current file:

cat /etc/fstab
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
LABEL=cloudimg-rootfs   /        ext4   discard,commit=30,errors=remount-ro     0 1
LABEL=UEFI      /boot/efi       vfat    umask=0077      0 1

Each non-comment line has six fields separated by spaces or tabs:

#FieldExampleDescription
1DeviceUUID=3f1c...What to mount: a UUID, LABEL, device path or network share
2Mount point/mnt/dataExisting directory where it will appear (none for swap)
3Typeext4Filesystem type: ext4, xfs, btrfs, vfat, swap, nfs4, cifs, tmpfs...
4Optionsdefaults,nofailComma-separated mount options, with no spaces
5Dump0Used only by the legacy dump backup tool. Use 0
6Pass2fsck order at boot: 1 for the root filesystem, 2 for other local ext filesystems, 0 to skip

Use 0 in the pass field for XFS and Btrfs (they do not use the boot-time fsck), swap, tmpfs and network filesystems. If a path contains a space, write it as \040, for example /mnt/my\040disk.

Identifying devices by UUID

Device names such as /dev/sdb1 or /dev/vdb1 are assigned in detection order and can change when you add a disk. Use an identifier that belongs to the filesystem itself instead. List them with:

lsblk -f -l
NAME   FSTYPE FSVER LABEL           UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
vda
vda1   ext4   1.0   cloudimg-rootfs 6c1d8e2a-51b4-4c3e-9f0a-7b2d91e4a3c5   31.2G    18% /
vda15  vfat   FAT32 UEFI            5A1B-2C3D                              98.3M     6% /boot/efi
vdb
vdb1   ext4   1.0   data            3f1c2b8e-6a7d-4e5f-9c1a-2b3d4e5f6a7b

You can reference a filesystem in field 1 in any of these ways:

FormExampleNotes
UUID=UUID=3f1c2b8e-...Recommended. Unique and set when the filesystem is created
LABEL=LABEL=dataReadable, but you must keep labels unique yourself
PARTUUID=PARTUUID=8d2e...GPT partition ID; survives reformatting the partition
Device path/dev/vdb1Avoid for data disks, the name can change

To print only the UUID of one partition, for example to paste it into fstab:

sudo blkid -s UUID -o value /dev/vdb1
3f1c2b8e-6a7d-4e5f-9c1a-2b3d4e5f6a7b

Common mount options

defaults expands to rw,suid,dev,exec,auto,nouser,async and is a good base. Add options after it, separated by commas:

OptionEffectTypical use
nofailBoot continues if the device is missing or fails to mountEvery non-essential data disk and network share
_netdevMarks a network filesystem, so systemd waits for the networkNFS, SMB, iSCSI
noatimeDoes not update the access time on every readBusy data and database disks
roMount read-onlyArchives, ISO images
noexec, nosuid, nodevDisallow executing binaries, setuid bits and device filesUpload directories, /tmp, removable media
noautoDo not mount at boot, only with mount /pathDisks you mount by hand
x-systemd.automountMount on first access instead of at bootNetwork shares that may be slow to respond
x-systemd.device-timeout=10sWait at most 10 seconds for the deviceDisks that may be detached
errors=remount-roext4: switch to read-only on filesystem errorsRoot filesystem

Ubuntu mounts filesystems with relatime by default, which already avoids most access-time writes, so noatime is a small optimization rather than a requirement.

Example entries

Replace the UUIDs, IPs and paths with your own. Each block below is a line you would add to /etc/fstab.

A local data disk

An ext4 data disk that does not block the boot if it is missing:

UUID=3f1c2b8e-6a7d-4e5f-9c1a-2b3d4e5f6a7b  /mnt/data  ext4  defaults,nofail  0  2

The same disk formatted with XFS, with noatime for a database, and pass 0:

UUID=9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d  /var/lib/postgresql  xfs  defaults,noatime,nofail  0  0

A swap file

Once a swap file exists and has been formatted with mkswap, this line activates it at boot:

/swapfile  none  swap  sw  0  0

A bind mount

A bind mount makes a directory visible at a second path. This is useful to expose a folder from a data disk where an application expects it:

/mnt/data/www  /var/www  none  bind,nofail  0  0

Bind mounts are processed in the order they appear in the file, so put this line after the entry that mounts /mnt/data.

A tmpfs in RAM

A tmpfs lives in memory and is emptied on every reboot. This entry limits it to 512 MB and hardens it:

tmpfs  /var/cache/app  tmpfs  defaults,size=512M,mode=1777,noexec,nosuid,nodev  0  0

An NFS share

Requires the nfs-common package on Ubuntu:

10.0.0.10:/srv/nfs/shared  /mnt/nfs/shared  nfs4  defaults,_netdev,nofail  0  0

An SMB/CIFS share

Requires the cifs-utils package. Keep the user name and password in a separate file readable only by root (chmod 600) instead of writing them in fstab, which any user can read:

//10.0.0.10/shared  /mnt/shared  cifs  credentials=/root/.smbcredentials,uid=1000,gid=1000,_netdev,nofail  0  0

Adding an entry safely

A mistake in /etc/fstab can stop the server at boot, so follow the same procedure every time. The example adds the ext4 data disk /dev/vdb1 at /mnt/data.

Step 1 - Backing up fstab

Keep a copy you can restore from the console if needed:

sudo cp /etc/fstab /etc/fstab.bak

Step 2 - Creating the mount point and testing a manual mount

The directory must exist before anything is mounted on it. Mounting by hand first proves the device and type are correct:

sudo mkdir -p /mnt/data
sudo mount -t ext4 /dev/vdb1 /mnt/data
findmnt /mnt/data
sudo umount /mnt/data

Step 3 - Adding the line

Open the file:

sudo nano /etc/fstab

Add the entry at the end, with the UUID you obtained from blkid:

UUID=3f1c2b8e-6a7d-4e5f-9c1a-2b3d4e5f6a7b  /mnt/data  ext4  defaults,nofail  0  2

Step 4 - Verifying the file

findmnt --verify parses the whole file and checks that devices exist, mount points are valid and filesystem types are known:

sudo findmnt --verify --verbose
/
   [ ] target exists
   [ ] UUID=6c1d8e2a-51b4-4c3e-9f0a-7b2d91e4a3c5 translated to /dev/vda1
   [ ] source /dev/vda1 exists
   [ ] FS type is ext4
...
/mnt/data
   [ ] target exists
   [ ] UUID=3f1c2b8e-6a7d-4e5f-9c1a-2b3d4e5f6a7b translated to /dev/vdb1
   [ ] source /dev/vdb1 exists
   [ ] FS type is ext4

0 parse errors, 0 errors, 0 warnings

Fix any error or warning before continuing.

Step 5 - Mounting from fstab

After every edit, tell systemd to regenerate its mount units from the file, then mount everything that is not mounted yet:

sudo systemctl daemon-reload
sudo mount -a
findmnt /mnt/data
TARGET    SOURCE    FSTYPE OPTIONS
/mnt/data /dev/vdb1 ext4   rw,relatime

mount -a prints nothing on success. If it returns an error, correct the line or restore the backup with sudo cp /etc/fstab.bak /etc/fstab.

Step 6 - Rebooting to confirm

Reboot while you still have the change fresh in mind, and check the mount once you reconnect:

sudo reboot
findmnt /mnt/data

If the entry is correct, the filesystem is mounted with the options you set.

Troubleshooting

The server boots into emergency mode. A filesystem without nofail could not be mounted. Open your provider's web console, log in as root, and look for the failing unit:

journalctl -xb | grep -i mount

The root filesystem is usually read-only at this point. Remount it read-write, restore the backup (or fix the bad line) and reboot:

mount -o remount,rw /
cp /etc/fstab.bak /etc/fstab
reboot

mount: /mnt/data: wrong fs type, bad option, bad superblock. The type in field 3 does not match the filesystem, an option is misspelled, or a helper package (nfs-common, cifs-utils) is missing. Check the real type with lsblk -f and the kernel message with sudo dmesg | tail.

mount: /mnt/data: mount point does not exist. Create the directory with sudo mkdir -p before mounting.

The boot waits 90 seconds for a device. systemd is waiting for a disk that is not there. Add nofail to the entry, and optionally x-systemd.device-timeout=10s to shorten the wait.

A network share is not mounted after boot. Make sure the entry includes _netdev and that the server is reachable. systemctl status mnt-nfs-shared.mount (the unit name is the mount path with slashes turned into dashes) shows the error.

Conclusion

You now know what each of the six /etc/fstab fields does, how to reference filesystems by UUID, which options matter in practice and how to add an entry with a backup, findmnt --verify and mount -a before you reboot. Next, you can use this procedure to add a new data disk, mount NFS or Samba shares permanently, or enable user and group disk quotas, which are also turned on through fstab options.