Fix for FW012 / FW999 / FW006 errors during QTS update (TVS-x73 and others)

Hi everyone,

I’m sharing a detailed walkthrough on how I bypassed the notorious FW999, FW012, and FW006 errors while updating a TVS-473e from QTS 5.2.5 to 5.2.8. If you’ve encountered “Invalid update image size” or “System update failed” despite having plenty of disk space, this is for you.

The Problem: Why the official update fails After a deep dive into the update logs and the behavior of update.sh, it appears there are two major flaws in the current QNAP update logic:

  1. RAMDisk Exhaustion (Error FW006): The update script tries to extract the firmware into /mnt/update, which often resides on a tiny RAMDisk (approx. 400MB). If the firmware and its extracted components exceed the free space there, the process dies with a “No space left on device” error.

  2. The “Schrödinger’s Mount” (Error FW999): The update_img.sh script attempts to mount the DOM partition (/dev/sdd2) to /root/FLASH_RFS1. In many cases, the mount actually succeeds, but the script misinterprets the return code or fails a subsequent sanity check, triggers a “cleanup” routine that deletes your extracted files, and then complains that the device is busy—because it just mounted it itself!

The Solution: Manual Update via “Surgical Intervention”

If you are comfortable with the CLI (and mcedit/vi!), here is the roadmap to success:

1. Create a workspace on your actual Data Volume Don’t let QNAP use the RAMDisk. Create a symlink to your large HDD volume.

mkdir -p /share/Public/fw_update
rm -rf /mnt/update
ln -sf /share/Public/fw_update /mnt/update 

2. Manually decrypt and extract the firmware Use the internal PC1 tool to get the actual fw.tar.

/sbin/PC1 d QNAPNASVERSION4 /share/Public/your_firmware.img /share/Public/fw_update/fw.tar
cd /share/Public/fw_update
tar xf fw.tar 

3. Fix the “Broken” Script Logic This is where we outsmart the SoftLab. Open update_img.sh (using mcedit or vi) and find the line that attempts to mount /dev/sdd2 to /root/FLASH_RFS1. Comment out that mount line (add a # at the beginning). Why? Because we will mount it manually, and we don’t want the script to panic when it tries to mount an already mounted partition. That’s how it looked after the edit:

mount_flash_rfs1()

{
  [ -d "$FLASH_RFS1_MP" ] || /bin/mkdir "$FLASH_RFS1_MP"
#  /bin/mount "$FLASH_RFS1" "$FLASH_RFS1_MP"
#  /bin/grep "$FLASH_RFS1_MP " /proc/mounts > /dev/null 2>&1
#  if [ $? -ne 0 ]; then
#    echo "mount $FLASH_RFS1 to $FLASH_RFS1_MP failed"
#    return 1
#  fi
  return 0
}

4. Prepare the environment and Run

#Ensure the mount point exists and the partition is mounted
mkdir -p /root/FLASH_RFS1
mount /dev/sdd2 /root/FLASH_RFS1

#Fake the version file for the logger
echo “5.2.8” > ./newver

#Run the actual image update script (the worker, not the wrapper)
./update_img.sh /share/Public/fw_update

5. Clean up and Reboot If you see “Update Finished”, you’ve won.

umount /root/FLASH_RFS1
reboot

Final thoughts for QNAP Devs It’s fascinating how the update script is sophisticated enough to check for secure boot support, yet it’s defeated by a partition that is “too successful” at being mounted. Perhaps adding a simple if ! mountpoint -q /root/FLASH_RFS1; then mount… would save users a lot of headaches? Just a thought. :wink:

Hope this helps someone else stuck in the FW999 loop!

2 Likes

Thank you very much for sharing! This information is very valuable to us. If you encounter any other issues or have further suggestions in the future, please feel free to let us know. Have a great day!

1 Like