TWRP / Failed to mount '/product' (invalid argument)

My FP3 is on /e/OS 1.8. For some reason magisk ceased to work. I patched the respective boot.img and flashed it, using TWRP, and the FP3 was rooted again. When it short after that unrooted again, I flashed the patched boot.img again, but to no avail, and worse, ending up in a bootloop.

I am able to decrypt the device, allowing me to save previously unsaved files to the extSDcard. But every time I boot the device into TWRP using fastboot, TWRP displays the error message “Failed to mount ‘/product’ (invalid argument)”.

I have tried to flash the patched boot.img and the unpatched one, both using TWRP and fastboot, but to no avail, leaving the device in a bootloop.

Is there anything else I can do before I restore a TWRP backup or even reinstall everything?

when mount outputs ‘invalid argument’ it’s mostly due to the filesystem or the filesystems specific mount options. Is there anything magisk alters on the product partition? I don’t know if the error message is relevant for the bootloop. If you have a product.img around from stockrom, you can flash that to the partition just to be sure it’s vanilla


I don’t know. I’d be happy if I knew.

I am having a hard time understanding your comment. What I understand is:

  1. I don’t find any product.img in /e/ custom roms. Hence there isn’t any product.img installed and I wonder why TWRP asks for it
  2. Yes, I have found a “product.img” in FPOS 10/Q.
  3. No, I havn’t found any “product.img” in FPOS11/R: it has “super_product.img”

I am actually clueless as to how to go about to flash that product.img (FPOS 10) to the actual /e/OS11 without messing everything up:
Using fastboot? (How should be the commands?)
Using TWRP?

I’d really appreciate any hint that would save me installing everything from scratch.

as said, maybe twrps message is not the sole issue.

Usually the shell script that Fairphones stockrom images includes explains what has to go where. I’d only flash the partition that fits your Major /e/ version and ignore the partitions that /e/ images itself provides (bar boot partition for your custom kernel).

Are you sure what state is on each partition A/B slot? as in: maybe you’re on the slot that has inconsistencies.

Sorry for my ideas not being a guide, it’s only ideas, I haven’t been in your situation exactly.

Do you think it’s worth trying to flash “product.img” (extracted from FPOS) only into the existing /e/OS10?

there have to be inconstencies on both slots, as bootloops occur on both slots. I’ve switched the slots multiple times.

Provided that flashing product.img doesn’t do the trick, what would be the necessary steps to restore an image of the same phone, but with /e/OS10/Q? Now the phone is on /e/OS11/R.

  1. Would I need to erase everything and install FPOS 10, wipe everything again, install /e/OS10 and then restore the TWRP image? I believe the tricky thing is to set the partitions right.
  2. Or can I directly proceed to restoring the TWRP image?

at that point I’d have already nuked the userdata and started up fresh, redoing the whole twrp partition image experiment.

what would be the necessary steps to restore an image of the same phone

I think just flashing /e/OS on one slot in any version should be enough to get things working again. You can leave userdata untouched (edit the shell script), but use the official boot.img to at least get it booting, then do the magisk edit?

Thanks for your ideas.

(I have quoted what I have asked you and what you might have misunderstood)
I meant that I have actually a TWRP image available which I could restore

sorry, I didn’t address your 2nd action point: yes, try your twrp partition images. If you never restored from them it’s a good test anyway.

My thought was: userdata is the only partition that matters (beyond the ones holding imsi/imei etc) - you can install /e/ of the version you had when things failed to one slot, but not format userdata. Holding off on magisk to check if this boots - I think this should work.

I’d probably do this first before the twrp restore.

In the meantime, I’ve tried this on slot B. Not good. Afterward:
error message

Warning: skip copying product_b image avb footer due to sparse image.
Sending ‘product_b’ (62016 KB) OKAY [ 2.037s]
Writing ‘product_b’ OKAY [ 0.620s]
Finished. Total time: 2.766s

  1. the desired outcome (phone working properly again), not achieved
  2. worse: TWRP didn’t start on slot B
  3. fortunately, I could change back to slot A, using “set_active”

(This is just FYI, not to blame you :roll_eyes:)

My idea is now to install /e/ on slot B in order to set the partitions right and clean up the mess I’ve made, omitting “data”, as per your suggestion.

What would be the necessary changes to the script (see below)?


#!/usr/bin/env bash


This script is created and maintained by


Feel free to connect for any queries or suggestions.



This script flashes a software release and complete wipes the device.

The script wipes both user data and the Google factory reset protection

information. It will unlock the phone, delete the data, and re-lock it.


set -e
set -u

Target device info

PRODUCT=“Fairphone 3”


ROOT_DIR=“$( cd – “$( dirname – “${BASH_SOURCE[0]}” )” &> /dev/null && pwd )”

Abort the script (and wait for a key to be pressed).

abort_now() {
echo “”
read -rp “ERROR: Aborting now (press Enter to terminate).” a
exit 1

Check for connected phone

find_device() {
echo “INFO: Looking for connected device(s)…”
while [ ${DEVICE_FOUND} = “false” ]

for sn in $(${FASTBOOT_BIN} devices | grep fastboot | grep -oE '^[[:alnum:]]+')
  # Checking the product ID
  PRODUCT_STRING=$(${FASTBOOT_BIN} -s "${sn}" getvar product 2>&1)
  # Add serial, if product matches
  if [[ ${PRODUCT_STRING} == *"${PRODUCT_ID}"* ]] || [[ ${PRODUCT_STRING} == *"${PRODUCT_ID_OLD}"* ]]
    serial_numbers="${serial_numbers} $sn"

case $(echo "${serial_numbers}" | wc -w | grep -oE '[0-9]+') in
    echo ""
    echo "WARNING: No ${PRODUCT} found in fastboot mode."
    echo "WARNING: Make sure that a ${PRODUCT} is connected."
      echo "INFO: One ${PRODUCT} in fastboot mode found (serial number: ${sn})."

    echo ""
    echo "WARNING: Several ${PRODUCT}'s in fastboot mode connected."
    echo "WARNING: Please connect only one ${PRODUCT}."

echo ""
while true
  read -rp "Do you want to look for a ${PRODUCT} again? [(Y)es/(n)o]: " a
  if [ -z "${a}" ] || [ "${a}" = 'y' ] || [ "${a}" = 'Y' ]
  elif [ "${a}" = 'n' ] || [ "${a}" = 'N' ]
    exit 0


Flash (or manipulate) relevant partitions

flash_device() {

flash_image_ab_or_abort “${sn}” modem “${IMAGES_DIR}/modem.img”
flash_image_ab_or_abort “${sn}” sbl1 “${IMAGES_DIR}/sbl1.img”
flash_image_ab_or_abort “${sn}” rpm “${IMAGES_DIR}/rpm.img”
flash_image_ab_or_abort “${sn}” tz “${IMAGES_DIR}/tz.img”
flash_image_ab_or_abort “${sn}” devcfg “${IMAGES_DIR}/devcfg.img”
flash_image_ab_or_abort “${sn}” dsp “${IMAGES_DIR}/dsp.img”
flash_image_ab_or_abort “${sn}” aboot “${IMAGES_DIR}/aboot.img”

flash_image_ab_or_abort “${sn}” boot “${IMAGES_DIR}/boot.img”
flash_image_ab_or_abort “${sn}” dtbo “${IMAGES_DIR}/dtbo.img”
flash_image_ab_or_abort “${sn}” system “${IMAGES_DIR}/system.img”
flash_image_ab_or_abort “${sn}” vbmeta “${IMAGES_DIR}/vbmeta.img”
flash_image_ab_or_abort “${sn}” vendor “${IMAGES_DIR}/vendor.img”
flash_image_or_abort “${sn}” userdata “${IMAGES_DIR}/userdata.img”
flash_image_ab_or_abort “${sn}” mdtp “${IMAGES_DIR}/mdtp.img”
flash_image_ab_or_abort “${sn}” lksecapp “${IMAGES_DIR}/lksecapp.img”
flash_image_ab_or_abort “${sn}” cmnlib “${IMAGES_DIR}/cmnlib.img”
flash_image_ab_or_abort “${sn}” cmnlib64 “${IMAGES_DIR}/cmnlib64.img”
flash_image_ab_or_abort “${sn}” keymaster “${IMAGES_DIR}/keymaster.img”
$FASTBOOT_BIN -s “${sn}” --set-active=a

echo “INFO: Locking bootloader”
“${FASTBOOT_BIN}” -s “${sn}” oem lock
echo “****** READ CAREFULLY ******”
echo “”
echo “INFO: The device is waiting for you to lock the bootloader.”
echo " You can do so on the device itself. Use the volume buttons"
echo " to choose the correct option, then the power button to select."
echo " The device will then reboot."
read -rp " Press any key to close this script." a
exit 0


Flash an image to a partition. Abort on failure.


flash_image_or_abort() {
local retval=0
$FASTBOOT_BIN -s “${1}” flash “${2}” “${3}” || retval=$?

if [ “${retval}” -ne 0 ]
echo “”
echo “ERROR: Could not flash the ${2} partition on device ${1}.”
echo “”
echo “ERROR: Please unplug the phone, take the battery out, boot the device into”
echo “ERROR: fastboot mode, and start this script again.”
echo “ERROR: (To get to fastboot mode, press Volume-Down and plug in the USB-C)”
echo “ERROR: (cable until the fastboot menu appears.)”

Flash an image to both A and B slot of partition. Abort on failure.


flash_image_ab_or_abort() {
flash_image_or_abort “${1}” “${2}_a” “${3}”
flash_image_or_abort “${1}” “${2}_b” “${3}”

Operating system checks and variable definition

os_checks() {
case “$(uname -s 2> /dev/null)” in
echo “INFO: You are using a Linux distribution.”
echo “INFO: You are using MinGW on Windows”
echo “ERROR: Unsupported operating system (${OSTYPE}).”
echo “ERROR: Only GNU/Linux, and MinGW on Windows are currently supported.”

echo “”
echo “*** ${PRODUCT} flashing script ***”
echo “”
echo “INFO: The procedure will start soon. Please wait…”
echo “Note that this will detect and flash only on FP3 or FP3+ devices.”
sleep 2

Begin with some OS checks and variable definition


Call function to look for device(s)

If only one device is found $sn will store its serial number


Flash the device


(triple backticks for code formatting - but anyway)

just ctrl+f for “userdata”, outcomment/delete that line, and within the function “flash_image_ab_or_abort()” (search for parantheses) delete one of the lines - let’s say the last, then it will flash _a

Thank you.

To make sure that I have understood you:
in order to restrict flashing “boot.img” to the boot partition on slot “B”, the line in the script would change from:

flash_image_ab_or_abort “${sn}” boot “${IMAGES_DIR}/boot.img” to
flash_image_b_or_abort “${sn}” boot “${IMAGES_DIR}/boot.img”,


no, you need to keep the function name to have a valid reference to the function - and edit the inside of the function itself where it is defined - not where it is called:

flash_image_ab_or_abort() {
  flash_image_or_abort “${1}” “${2}_a” “${3}”
  flash_image_or_abort “${1}” “${2}_b” “${3}” # remove or outcomment this line -> no flash to slot_b will occur

Thank you.

In order to keep the userdata, is it accurate to just outcomment the following line?
flash_image_or_abort "${sn}" userdata "${IMAGES_DIR}/userdata.img"
leaving it like this:
# flash_image_or_abort "${sn}" userdata "${IMAGES_DIR}/userdata.img"

yep that’s accurate.

Thank you. I’ve run the install script for /e/1.4 as discussed:

  1. I ran it with the restriction to slot B and leave userdata alone - consequence: total bust - /e/ recovery appeared with 2 options only: “Try again” and “Factory data reset”
  2. I ran it leaving userdata alone - /e/ recovery appeared with 2 options only: “Try again” and “Factory data reset”

Boot with TWRP works, though.

I wonder whether there is any means to keep the userdata.

At least there is now nothing left in “/storage” (viewed with the TWRP file manager); /data/data is encrypted.

I guess that, having come from /e/1.8, I need to scour clean the partitions or just the data partition, in order to run the install script for /e/1.4 and have a clean install of 1.4? As mentioned, my goal is to restore a TWRP image made of 1.4.

with that in mind, as there isn’t critical loss I’d start fresh. And test again with newly made twrp backups, if they’re a viable route at all.

Thank you. I have run into problems starting fresh and started a new thread here

1 Like