When file browsing with nautilus the thumbnails of the pictures don't get generated. Instead we can see ~/.cache/thumbnails/fail/gnome-thumbnail-factory being created with all the hashed failed thumbnails in here.
This is caused by an issue with bwrap that nautilus uses to call its thumbnailers programs.
The issue is twofold:
first edit /usr/bin/bwrap which is in fact a wrapper around bwrap coming from flatpak-hybris package, see the diff at the end of this post. The issue with this wrapper is that then using "--args" option of bwrap arguments are correctly managed, but without this option the arguments are duplicated, a simple test to see what I mean, run bwrap --ro-bind / / echo first_arg second_arg which results in "first_arg second_arg --ro-bind / / echo first_arg second_arg" being displayed instead of just "first_arg second_arg".
then, nautilus is calling bwrap with both "--proc" and "--unshare-all" options at the same time and there seems to be a bug in the bwrap version used where if called with both this option at the same time we get an error, example with a simple command: "/usr/bin/bwrap --ro-bind / / --proc /proc --unshare-all echo test bwrap: Can't mount proc on /newroot/proc: Device or resource busy". If you just remove either --proc /proc or --unshare-all from this test command bwrap is working correctly. So in order to fix this I used a wrapper script in my PATH (which I placed in ~/bin but can be anywhere in a directory in the PATH before /usr/bin/). See the content of the script after the patch.
Now thumbnails are correctly generated.
Hope this helps.
Patch:
--- /root/bwrap.origin 2025-08-30 17:22:02.720761141 +0200
+++ /usr/bin/bwrap 2025-08-30 14:44:46.891836095 +0200
@@ -8,13 +8,14 @@
fi
# Handle --args case
+args=()
if [[ "$1" == "--args" ]]; then
shift 1
fd=$1
shift 1
readarray -d '' args < /dev/fd/$fd
-else
- args=("$@")
+#else
+ #args=("$@")
fi
# this seems to be a common issue on arm64. when unsharing pid and user in conjunction it throws an error message.
@@ -28,5 +29,5 @@
esac
done
-args=("${args[@]}")
+#args=("${args[@]}")
exec "$BWRAP" "${args[@]}" "$@"
Wrapper script:
#!/bin/bash
gdk_pixbuf_thumbnailer_detected=false
for arg in "$@"; do
case "$arg" in
/usr/bin/gdk-pixbuf-thumbnailer)
gdk_pixbuf_thumbnailer_detected=true
;;
esac
done
args=( "$@" )
if $gdk_pixbuf_thumbnailer_detected; then
args=()
for arg in "$@"; do
case "$arg" in
--proc|/proc)
continue
;;
esac
args+=( "$arg" )
done
fi
exec /usr/bin/bwrap "${args[@]}"
If the fix with the patch is done, there is no need for the wrapper script in the PATH as the fixed script already discard one of the option ("--unshare-all" in this case). So only the patch is needed.
But a better patch as I didn't see that the args array is used to check for the arguments to unset them, so a simpler patch is to just remove the "$@" being given a second time as it was already saved in the args array in the first place, so this simpler patch is all that is needed:
This fix is not working when using --args it misses the "$@" from the args, so it needs to be added back but before processing the search for "--unshare-all". This version of the patch is a better fix: