Let me take you on a short journey (tl; dr at the bottom), I don’t necessarily ask any questions or seek any response, I only report on my experience in the hope it might help somebody else.
Setup description
I tried to set up Immich on a TrueNAS Scale for home use lately. To make access to images comfortable for users, I have placed the library on a dataset that is also accessible over the local network (and SFTP in the future).
Issue description
The issue arose when I turned on the storage template in Immich and neither existing or newly uploaded photos ended up in the library. Photos kept to be uploaded by a mobile app(s) to users’ upload folders, and Immich tried to move files into their respective library folders (following a storage template configured in Immich).
Symptoms
No matter what I tried, photos never arrived in the library. I run various (re)jobs (from storage template migration to metadata extraction and smart search. Subfolders were created in the library per user and in accordance with Immich’s storage template, but no files were there. The empty folder structure appeared or disappeared, depending on various jobs run in/by Immich.
Logs
That prompted me to chase logs where I found the following error:
[Microservices:StorageTemplateService] Error: EPERM: operation not permitted, copyfile ‘upload/upload///.jpg’ → ‘upload/library///.jpg’
The log entry was accompanied by the following stack trace:
at async Object.copyFile (node:internal/fs/promises:623:10)
at async StorageCore.moveFile (/usr/src/app/dist/cores/storage.core.js:160:17)
at async /usr/src/app/dist/services/storage-template.service.js:153:17
at async /usr/src/app/dist/repositories/database.repository.js:199:23
ERROR [Microservices:StorageTemplateService]
Object:
{
"id": "0c520605-be1e-4129-909f-1327c82cd05b",
"oldPath": "upload/upload/<user-id>/<hashed-path>/<unique-photo-id>.jpg",
"newPath": "upload/library/<user-label>/<template-based-path>/<original-file-name>.jpg"
}
This was a bit weird since I run immich as a TrueNAS application and this particular installment runs under the root
user. I double-checked that by running the id
command in Immich’s container (located at the same part of the UI that the logs come from in Apps) and I also double-checked that both underlying dataset permissions and container mount permissions were correct - they were.
Net answers
In the pursuit of understanding the issue and fixing the problem for users, I searched the web for quite some time.
Searching the web for the error itself does not seem to yield particularly useful results as most mentions were developer-oriented (from sites like Stack Overflow or GitHub).
Then I stumbled upon this thread that describes the very same issue. Community forums are now read-only (even though the post is almost recent), hence I decided to write a post like this if I ever solve the issue.
Fortunately, there was yet another source of profound net wisdom: Reddit. In one of the threads where yet another unlucky user faces this misconfiguration-induced despair, there lays this hidden jam of an answer. I will quote:
Immich successfully creates the dated folders under Library/admin/ but cannot copy or move files into it. For fun I connected to the console of the microservices container and ran this command:
cp /usr/src/app/upload/upload/<…>.JPG usr/src/app/upload/library/<…>.JPG
The image was successfully copied so (like you) I felt like this eliminated a permissions issue.
However, the user was not done yet as they found a thread on the TrueNAS community forum (read-only again). That allowed them to uncover the underlying issue and find the fix for themselves as well as me - and hopefully others too:
chmod fails on my dataset which is by design with the ACL Mode set to restricted. chmod is effectively disabled in favor of NFS ACL. My guess is that the node.js copyfile function is using chmod internally and returning an error. When I set ACL Mode to passthrough it instantly fixed my issue.
Summary
If you:
- deployed Immich in TrueNAS Scale (or used ZFS file system for its library in general, I guess)
- placed its library on a ZFS dataset that has ACL Type set to
SMB/NFSv4
(made it a shared drive of your TrueNAS, for example] - used or started using Immich’s storage template to upload files from mobile device(s) to Immich’s built-in library
- experience lack of files in the designated library folder, no matter what immich jobs you run
Then:
- Go to the ZFS dataset closest to the location of your Immich library
- Set ACL mode to
Passthrough
- Run the Storage template migration job from within the Immich instance to move files your (users’) mobile app(s) already uploaded to immich