Skip to content

Mount external drive under the same volume name on macOS

macOS may change the mount point every time you unplug and replug an external drive causing a number of issues when you have your job folders located on that drive, one of which being Agent creating a phantom mount point on the internal storage device. Follow this guide to pin a volume to a fixed mount point so it always mounts in the same location.

Prerequisites

  • macOS administrator privileges.
  • The external drive connected to your Mac.
  • Passphrase for the drive if it is encrypted.

Change the external drive's mount point

  1. Pause your jobs in the Management Console, then quit the Resilio Agent.

    1. In the Management Console, select Jobs.
    2. In the Job Runs tab, locate and select the job you want to pause, then click Pause.
    3. Close the Resilio Agent:

      Menu bar

      Click the Resilio Agent icon in the menu bar, then select Quit.

      Activity Monitor

      Open Activity Monitor, locate and select the Resilio Connect Agent process, then click Quit Process.

      Terminal

      In Terminal, run the following command:

      osascript -e 'if application "Resilio Connect Agent" is running then tell application "Resilio Connect Agent" to quit'
      

      Note

      • The first time you run this, macOS asks if Terminal may control Resilio Connect Agent. You must allow it to run the command successfully.
      • Make sure to include the if … is running part: without it, AppleScript can launch the Agent in order to quit it.
    4. Run the following command to confirm the Agent process is not running:

      pgrep -l -f "Resilio Connect" || echo "Agent not running"
      

      If the Agent is not running, you should see the following output:

      Agent not running
      

      If the command returns a process ID and name, the Agent is still running. Try quitting it again, or use Activity Monitor to force quit it.

      Note

      Opened files may prevent Resilio Agent from closing gracefully. Check if the Agent didn't report an application preventing shutdown. If that's the case, close those files, then try again.

      Background service

      The Agent can also be installed as a background service, in which case there is no menu bar icon and the process restarts right after you terminate it. Stop it with whichever of these two files exists on your Mac:

      sudo launchctl unload -w /Library/LaunchAgents/com.resilio.agent.plist
      sudo launchctl unload -w /Library/LaunchDaemons/com.resilio.agentdaemon.plist
      

      One of the two will report that the file doesn't exist. That's expected — run both and ignore the error. Load it again the same way with load in place of unload when you reach Step 9.

  2. Determine the drive mount location.

    1. In Terminal, run the following command:

      ls -la /Volumes/
      

      If there are two entries with your drive, one of which with a numeral suffix (for example, CGxResilio and CGxResilio 1), you have the collision described above. One of them is the actual drive the other is a phantom copy.

      Note

      If you only see one entry, skip step 4.

    2. To determine which is which, run the following command:

      df -h "/Volumes/CGxResilio"
      
      • Filesystem column shows your boot storage device

        /dev/disk3s5   ...   /System/Volumes/Data
        

        If the filsystem column shows your boot storage device, then that folder is a phantom instance on your internal storage device, not your external drive. Note it down — you'll need it later in this guide.

      • No such file or directory

        If the df command's output reports No such file or directory, that path simply doesn't exist, which is fine.

    3. Run the following command to establish mount details for the drive:

      mount | grep -i "CGxResilio"
      

      Anything that appears in ls /Volumes/ command's output but is not present on this list is a folder pretending to be a drive.

  3. Retrieve the drive's UUID and filesystem type.

    The UUID is the drive's permanent fingerprint which you can use to pin the mount point.

    1. In Terminal, run the following command:

      diskutil list external
      
    2. Look for the line containing APFS Volume (or Apple_HFS on older drives) followed by your drive's name. The value in the IDENTIFIER column is the UUID, for example, disk5s1.

      /dev/disk4 (external, physical):
         #:         TYPE NAME                SIZE       IDENTIFIER
         0: GUID_partition_scheme          *4.0 TB     disk4
         1:    Microsoft Reserved           16.8 MB    disk4s1
         2:  Apple_APFS Container disk5     4.0 TB     disk4s2
      
      /dev/disk5 (synthesized):
         1:      APFS Volume CGxResilio     1.4 TB     disk5s1
      

      Important: Choosing correct identifier

      • Do not use the physical disk (disk4) or the first slice. In the example above, disk4s1 is a 16.8 MB Microsoft Reserved partition with no filesystem on it at all — trying to mount it returns Inappropriate file type or format.
      • Do not write disk identifiers down to use them later - They are assigned in the order they are plugged-in thus are subject to change.
    3. Run the following command to read the volume's details.

      diskutil info disk5s1 | grep -Ei "Volume Name|Mounted|File System Personality|Volume UUID|FileVault"
      

      Example output

      Volume Name:               CGxResilio
      Mounted:                   Yes
      File System Personality:   APFS
      Volume UUID:               C6F660A5-1497-40F5-A253-68E8BD2FC0FC
      FileVault:                 Yes (Unlocked)
      

      Take note of the following:

      • The Volume UUID, exactly as shown.
      • The File System Personality — usually APFS, sometimes HFS+ (write this down in lowercase: apfs or hfs respectively).
      • Whether FileVault says Yes. If it does, Step 7 is mandatory. On an HFS+ drive there may be no FileVault line at all — that means no, and you can skip Step 7.
  4. Move the leftover folder.

    The leftover folder contains hidden bookkeeping files that may be needed for troubleshooting and recovery should a sync go wrong. Move it aside and keep it for a week or two before deleting it.

    sudo mv "/Volumes/CGxResilio" "/Users/Shared/_stale-CGxResilio-$(date +%Y%m%d)"
    

    Resource busy or operation not permitted

    Resource busy or operation not permitted errors mean that the folder is still in use. Eject the drive in Finder, run ls -la /Volumes/ again, and see whether the folder is still there. If it still appears after the eject, it's a phantom.

  5. Create the permanent mount point.

    In Terminal, run the following command to create a folder that will serve as the mount point for the drive:

    sudo mkdir -p /Users/Shared/CGxResilio
    

    Why not /Volumes?

    /Volumes belongs to the disk arbitration background service, which manages entries under /Volumes and is responsible for appending the numbers.

  6. Add an entry to /etc/fstab.

    /etc/fstab is the file that instructs macOS where to mount specific volumes.

    Warning

    Use vifs to edit the file, which takes a lock on the file while you're working on it. Opening it in TextEdit may corrupt it.

    1. Verify if there's already an entry associated with the drive.

      cat /etc/fstab
      

      On a new Mac you should see five comment lines beginning with # and nothing else. If a line mentioning your drive is already present, edit it rather than adding another.

    2. Add an entry in /etc/fstab.

      (Recommended) Semi-automatically using Terminal

      Run the following command to add the entry to /etc/fstab without having to type the UUID or filesystem type by hand. Only change the drive's name in the first quotes "CGxResilio".

      VOL="CGxResilio"; ID=$(diskutil list | awk -v v="$VOL" '$0 ~ ("(APFS Volume|Apple_HFS)[[:space:]]+" v "[[:space:]]") {print $NF}'); INFO=$(diskutil info "$ID" 2>/dev/null); U=$(printf '%s\n' "$INFO" | awk -F': *' '/Volume UUID/{print $2; exit}'); P=$(printf '%s\n' "$INFO" | awk -F': *' '/File System Personality/{print $2; exit}'); case "$P" in *APFS*) T=apfs;; *HFS*) T=hfs;; *) T="";; esac; MP="/Users/Shared/${VOL// /}"; if [ -z "$U" ] || [ -z "$T" ]; then echo "Lookup failed for '$VOL' - check the name with: diskutil list external"; else echo "Adding:  UUID=$U $MP $T rw"; sudo -v && sudo mkdir -p "$MP" && { cat /etc/fstab; echo "UUID=$U $MP $T rw"; } | sudo env EDITOR=/usr/bin/tee vifs >/dev/null && echo "--- /etc/fstab now ---" && grep -F "$U" /etc/fstab; fi
      

      Expected output

      Adding:  UUID=C6F660A5-1497-40F5-A253-68E8BD2FC0FC /Users/Shared/CGxResilio apfs rw
      --- /etc/fstab now ---
      UUID=C6F660A5-1497-40F5-A253-68E8BD2FC0FC /Users/Shared/CGxResilio apfs rw
      

      Note

      • If the name doesn't match a connected drive, the command outputs Lookup failed error message and does not make any changes in the /etc/fstab file.
      • The command also creates the mount point, so you can skip Step 5 if you use this. Drive names with spaces get a mount point with the space removed - for example, Media Drive becomes /Users/Shared/MediaDrive — and the path it prints is the one to give Resilio in Step 9.
      Manually by editing the /etc/fstab file

      Use this if the command above failed, or if you'd rather see the file.

      1. In Terminal, run the following command to open /etc/fstab in vi:

        sudo vifs
        
      2. Press G (capital) to jump to the last line.

      3. Press o (lowercase) to enable typing mode in a new line.
      4. Type your entry, using your own UUID:

        UUID=C6F660A5-1497-40F5-A253-68E8BD2FC0FC /Users/Shared/CGxResilio apfs rw
        
      5. Press Esc to exit the typing mode.

      6. Type :wq and press Return to write your changes and quit the editor.

      If your drive's mount point contains spaces

      The /etc/fstab file splits each line on spaces, so a mount /Users/Shared/Media Drive is read as two separate fields and the entry does not serve its purpose. In that case, make sure to replace space characters with \040:

      UUID=A1B2C3D4-0000-1111-2222-333344445555 /Users/Shared/Media\040Drive apfs rw
      

      To avoid escaping spaces, a simpler alternative is to create the mount point without the space — sudo mkdir -p /Users/Shared/MediaDrive — and use that path here. The folder name does not have to match the drive name, and a path without spaces saves you quoting every command from here on.

      1. Run the following command to verify that the entry was added correctly:

        grep CGxResilio /etc/fstab
        

        Expected output

        UUID=C6F660A5-1497-40F5-A253-68E8BD2FC0FC /Users/Shared/CGxResilio apfs rw
        

        If the command's output is empty, run sudo vifs and try again.

  7. Save the passphrase to your keychain (applicable to encrypted drives).

    1. Eject the drive in Finder.
    2. Unplug it, then plug it back in.
    3. When macOS asks for the drive's passphrase, select Remember this password in my keychain before you proceed with unlocking the drive.

      Tip

      If you're not prompted to enter the passphrase, it may already be stored in your keychain.

  8. Verify the drive mounts correctly.

    1. Eject the drive in Finder, then unplug it from your Mac.
    2. Wait 5 seconds, then plug it back in.
    3. In Terminal, run the following command:

      mount | grep "/Users/Shared/"
      

      Expected output

      /dev/disk5s1 on /Users/Shared/CGxResilio (apfs, local, nodev, nosuid, journaled)
      
    4. Run the following command to confirm your media is available:

      ls -la /Users/Shared/CGxResilio
      

      If the folder is empty, the drive must have mounted somewhere else — check ls -la /Volumes/ and go back to step 4.

  9. Point Resilio to the new location and restart.

    1. In the Management Console, open each job that used the old path and change it to the new one. For example /Volumes/CGxResilio 1/ProjectName > /Users/Shared/CGxResilio/ProjectName.
    2. Then launch the Resilio Agent and resume the jobs.

    Cannot mount folder: the chosen path location is not empty

    Caching and Hybrid Work jobs require a completely empty destination folder. Existing hidden files prevent Resilio from mounting the folder and resuming those jobs. Don't delete them yet. Point the job at a new, empty folder alongside the old one (ProjectName-new), let it fully synchronize, verify the files, and only then clear out the original folder.

    Throughput during indexing

    You may experience slower than expected transfer speeds while the job is indexing its dataset.

Troubleshooting

Error message Description
mount: … failed with 66 The mount helper couldn't open the device — most likely due to a locked encrypted volume, or disconnected drive.
Solution: Step 7, then Step 8
mount_apfs: … Operation not permitted Encrypted volume is locked.
Solution: Step 7
mount_apfs: … Inappropriate file type or format The selected partition has no filesystem on it.
Solution: Step 3
This is an encrypted and locked APFS Volume Encrypted volume is locked.
Solution: Step 7
vifs: editing error The editor couldn't launch. Nothing was written — your fstab remains unchanged.
Solution: Step 6, interactively
Unmount failed for … A process has the files open on the volume.
Solution:
  • Quit the agent
  • Close Finder windows
  • Run sudo lsof /Users/Shared/CGxResilio
Drive still mounts as “… 1” A phantom folder is back in /Volumes — the Agent was most likely running.
Solution: Step 1, then Step 4
zsh: no such file or directory A path is missing its leading slash - Users/Shared/… and not /Users/Shared/…
Solution: Retype with the slash.
osascript: not authorised to send Apple events macOS blocked Terminal from controlling the Agent.
Solution: Allow it in System Settings > Privacy & Security > Automation, or quit from the menu bar
Another drive stopped mounting An overwrite-style fstab command wiped its entry.
Solution: Re-add it; use the Step 6 command from now on.
Agent restarts after you quit it Agent runs as a background service, not an app.
Solution: Step 1, launchctl command.
Entry is in fstab but nothing mounts Most often a non-escaped space character in the mount point, or a missing UUID.
Solution: Step 6; verify with cat /etc/fstab
diskutil: Unable to find disk for A variable was empty — usually a lookup one-liner run in a different Terminal window.
Solution: Rerun the lookup first
Cannot mount folder: path is not empty Resilio requires an empty destination folder. It's most likely that the destination path contains hidden files.
Solution: Step 9

Rolling out this change to a team

UUIDs are unique and must be determined for each machine. What is identical across machines is the procedure and the mount point convention.

Establish a convention and have everyone adhere to it, for example /Users/Shared/<DriveName>. When a job path has the same structure on every machine, an incorrect one is easily spotted.

When carrying out the procedure, make sure to:

  • Quit the agent first.
  • Don't reuse disk numbers.
  • Don't skip the keychain checkbox on encrypted drives.

Condensed alternative (optional)

Instructions in this section are an alternative to steps 3 to 6 above.

  • Look up the UUID by drive name
    Avoids disk numbers entirely. Change CGxResilio to your drive's name:

    VOL="CGxResilio"; ID=$(diskutil list | awk -v v="$VOL" '$0 ~ ("(APFS Volume|Apple_HFS)[[:space:]]+" v "[[:space:]]") {print $NF}'); if [ -z "$ID" ]; then echo "No volume named '$VOL' - check the name with: diskutil list external"; else echo "identifier: $ID"; diskutil info "$ID" | grep -Ei "Volume Name|File System Personality|Volume UUID|FileVault"; fi
    

    If two drives share a name this command outputs two identifiers and won't work — fall back to step 3. Names are case-sensitive. A name containing brackets or other special characters can also confuse the pattern; step 3 is always the reliable route.

  • Add the fstab entry without using vi

    This appends your line while preserving everything already in the file. Run the lookup above first, in the same Terminal window, so $ID is set. Edit the mount point in the command to match yours:

    UUID=$(diskutil info "$ID" | awk -F': *' '/Volume UUID/{print $2; exit}'); if [ -z "$UUID" ]; then echo "No UUID found - run the lookup one-liner above first."; else sudo -v && { cat /etc/fstab; echo "UUID=$UUID /Users/Shared/CGxResilio apfs rw"; } | sudo env EDITOR=/usr/bin/tee vifs >/dev/null && grep -F "$UUID" /etc/fstab; fi
    

    Note

    Why it's written oddly?
    vifs hands its locked temporary copy of the file to whatever $EDITOR points at, and it runs that value directly as a program. A value containing arguments — sh -c '…' — can't be run that way, so vifs reports editing error and discards the edit. /usr/bin/tee is a real binary that takes the temp file as its only argument, so it works. sudo env is needed because sudo strips environment variables by default.

    Why the guard matters?
    Without the if [ -z "$UUID" ] check, an unset $ID — a new Terminal tab is enough — produces the line UUID= /Users/Shared/… apfs rw. It has the right number of fields, saves without complaint, and never mounts anything.

    One version to avoid
    A shorter variant that circulates pipes a fixed block of text into tee — the five comment lines plus your entry. It overwrites the whole file instead of appending to it.
    On a Mac that has never had an fstab entry, it works and looks identical. On a Mac that already has one — a second drive pinned earlier, which is exactly what happens as you roll this out — it deletes that entry.
    The cat /etc/fstab in the commands on this page is the entire difference. Prefer the one in Step 6, which also spares you typing the UUID.

The whole procedure as a script

Use the following script to pin a drive to a mount point under /Users/Shared. The script shows you what it's about to do an waits for yoru confirmation.

Note

The script does not delete anything, does not touch /Volumes, and does not stop your Agent.

To use the script:

  1. Copy the script below and save it as pin-drive.sh.
  2. Run the following command to change the permissions:

    chmod +x pin-drive.sh
    
  3. Run the script:

    ./pin-drive.sh CGxResilio
    

    Note

    If your drive's name has a space in it, provide a second argument with the folder name in quotes: ./pin-drive.sh "Media Drive" MediaDrive.

#!/bin/bash
# pin-drive.sh (v2) - Pin an external volume to a fixed mount point under
# /Users/Shared, so macOS stops mounting it as "Name 1", "Name 2", etc.
#
#   Usage:  ./pin-drive.sh <VolumeName> [MountFolderName]
#
#   ./pin-drive.sh CGxResilio               -> /Users/Shared/CGxResilio
#   ./pin-drive.sh "Media Drive" MediaDrive -> /Users/Shared/MediaDrive
#
# The second argument is worth using whenever the drive's name contains a
# space: a mount point without spaces keeps every later terminal command
# simple. If you omit it, the script escapes the space correctly anyway.
#
# Before running: stop the Resilio Connect Agent (see notes at the end).
# After running:  eject and replug the drive, then check with
#                 mount | grep "/Users/Shared/"
#
# This script does NOT delete anything, does not touch /Volumes, and does not
# stop your agent. Those steps need a human looking at them.

set -euo pipefail

[ "$(uname -s)" = "Darwin" ] || { echo "This script is for macOS only."; exit 1; }

VOL="${1:-}"
if [ -z "$VOL" ]; then
  echo "Usage: $0 <VolumeName> [MountFolderName]"
  echo "Tip:   diskutil list external    # shows the names of connected drives"
  exit 1
fi
FOLDER="${2:-$VOL}"
MP="/Users/Shared/$FOLDER"

# --- Locate the volume by name. Never by disk number: those are handed out in
# --- plug-in order and change between reconnects.
# --- 'APFS Volume <name>' covers APFS; 'Apple_HFS <name>' covers HFS+.
MATCHES=$(diskutil list \
  | awk -v v="$VOL" '$0 ~ ("(APFS Volume|Apple_HFS)[[:space:]]+" v "[[:space:]]") {print $NF}')
COUNT=$(printf '%s\n' "$MATCHES" | grep -c . || true)

if [ "$COUNT" -eq 0 ]; then
  echo "No volume named '$VOL' found."
  echo
  echo "Names are case-sensitive and must match exactly. Volumes seen now:"
  diskutil list | awk '/APFS Volume|Apple_HFS/ {$1=""; print "   " $0}'
  exit 1
fi
if [ "$COUNT" -gt 1 ]; then
  echo "Found $COUNT volumes named '$VOL'. Too ambiguous to do safely."
  echo "Identify the right one with 'diskutil list external' and set it up by hand."
  exit 1
fi
ID="$MATCHES"

INFO=$(diskutil info "$ID")
UUID=$(printf '%s\n' "$INFO" | awk -F': *' '/Volume UUID/             {print $2; exit}')
FS=$(printf   '%s\n' "$INFO" | awk -F': *' '/File System Personality/ {print $2; exit}')
FV=$(printf   '%s\n' "$INFO" | awk -F': *' '/FileVault/               {print $2; exit}')
LOC=$(printf  '%s\n' "$INFO" | awk -F': *' '/Device Location/         {print $2; exit}')

case "$FS" in
  *APFS*) TYPE="apfs" ;;
  *HFS*)  TYPE="hfs"  ;;
  *) echo "Unsupported or unrecognised filesystem: '$FS'"; exit 1 ;;
esac

# A missing UUID would produce a malformed fstab line that still looks fine.
case "$UUID" in
  ????????-????-????-????-????????????) : ;;
  *) echo "Did not get a usable Volume UUID for $ID (got: '${UUID:-empty}')."
     echo "Set this up by hand instead - see Step 3 of the runbook."
     exit 1 ;;
esac

# fstab is whitespace-separated, so a space in the path must be written \040.
MP_FSTAB=${MP// /\\040}
LINE="UUID=$UUID $MP_FSTAB $TYPE rw"

# The finished line must be exactly 4 fields or it will never mount.
FIELDS=$(printf '%s\n' "$LINE" | wc -w | tr -d ' ')
[ "$FIELDS" -eq 4 ] || { echo "Built a malformed fstab line ($FIELDS fields). Aborting."; exit 1; }

echo
echo "  volume       $VOL  ($ID)"
echo "  filesystem   $FS"
echo "  location     ${LOC:-unknown}"
echo "  filevault    ${FV:-No}"
echo "  mount point  $MP"
echo "  fstab line   $LINE"
echo

if [ "${LOC:-}" = "Internal" ]; then
  echo "WARNING: this volume reports as Internal, not External."
  echo "         Pinning an internal volume is almost certainly a mistake."
  echo
fi

if grep -qF "$MP_FSTAB" /etc/fstab 2>/dev/null; then
  echo "An entry for $MP already exists in /etc/fstab. Nothing to do."
  echo "Current entry:"
  grep -F "$MP_FSTAB" /etc/fstab | sed 's/^/   /'
  exit 0
fi

read -r -p "Apply this? [y/N] " OK || { echo; echo "No answer received. Nothing was changed."; exit 1; }
case "$OK" in
  y|Y|yes|YES) : ;;
  *) echo "Cancelled. Nothing was changed."; exit 0 ;;
esac

# Authenticate once up front so the password prompt doesn't land mid-pipeline.
sudo -v

sudo mkdir -p "$MP"

# vifs runs $EDITOR directly as a program, so $EDITOR cannot carry arguments -
# an editor string like "sh -c '...'" gives "vifs: editing error" and the edit
# is discarded. /usr/bin/tee is a real binary that takes the locked temp file
# as its only argument. Piping the current fstab plus our line APPENDS rather
# than overwrites, which matters on any machine with existing mount entries.
{ cat /etc/fstab 2>/dev/null; printf '%s\n' "$LINE"; } \
  | sudo env EDITOR=/usr/bin/tee vifs >/dev/null

echo
if grep -qF "$MP_FSTAB" /etc/fstab; then
  echo "Written to /etc/fstab:"
  grep -F "$MP_FSTAB" /etc/fstab | sed 's/^/   /'
else
  echo "Write failed - /etc/fstab is unchanged."
  exit 1
fi

case "$FV" in
  Yes*)
    echo
    echo "NOTE: this volume is encrypted. Eject and reconnect it, and tick"
    echo "      'Remember this password in my keychain' at the unlock prompt."
    echo "      Without that it can never mount on its own."
    ;;
esac

cat <<NEXT

Next steps
  1. Stop the Resilio Connect Agent. Quitting from the menu bar is enough
     only if it runs as a normal app. If it was installed as a service,
     quitting does nothing and you need whichever of these exists:
       sudo launchctl unload -w /Library/LaunchAgents/com.resilio.agent.plist
       sudo launchctl unload -w /Library/LaunchDaemons/com.resilio.agentdaemon.plist
  2. Eject and replug the drive.
  3. Confirm:
       mount | grep "$MP"
     You should see $MP with no number after it.
NEXT