opencloud icon indicating copy to clipboard operation
opencloud copied to clipboard

Download of multiple files failing on public links

Open tommyknows opened this issue 2 months ago • 9 comments

Describe the bug

I have a shared, public link on a folder with "Can edit (View, upload, edit, download, delete)" permissions, and can access and view files & directories in that folder. I can also download files one by one, however trying to download multiple files at once returns an error 'Failed to download the selected files."

Note that as a logged-in user I have no problems downloading files.

Steps to reproduce

  1. Create a public link
  2. Open the public link, select more than one file and click the "download" button

Expected behavior

Downloading of multiple files should work.

Actual behavior

Error message 'Failed to download the selected files'.

In the backend, I can see the the following logs:

{"level":"error","service":"proxy","error":"gateway: grpc failed with code CODE_PERMISSION_DENIED","time":"2025-10-25T13:08:19Z","message":"error when calling Createhome"}
{"level":"error","service":"gateway","host.name":"opencloud-679444ff47-79d4k","pkg":"rgrpc","traceid":"77fc0a08975724beff160a095da08d7d","error":"error: permission denied: access forbidden via public link","ref":{"resource_id":{"storage_id":"9160e783-c388-4f99-9454-670a858b38f7","opaque_id":"82871925-9c76-43c0-86b9-aca5df7f96b3","space_id":"96458d93-d65f-4245-9b42-68751f04ab48"},"path":"."},"scope":"publicshare:snYnZpgdaMikAkP","time":"2025-10-25T13:08:19Z","message":"error resolving reference under scope"}
{"level":"error","service":"gateway","host.name":"opencloud-679444ff47-79d4k","pkg":"rgrpc","traceid":"77fc0a08975724beff160a095da08d7d","error":"error: permission denied: access forbidden via public link","ref":{"resource_id":{"storage_id":"9160e783-c388-4f99-9454-670a858b38f7","opaque_id":"82871925-9c76-43c0-86b9-aca5df7f96b3","space_id":"96458d93-d65f-4245-9b42-68751f04ab48"},"path":"."},"scope":"publicshare:snYnZpgdaMikAkP","time":"2025-10-25T13:08:19Z","message":"error resolving reference under scope"}
{"level":"error","service":"gateway","host.name":"opencloud-679444ff47-79d4k","pkg":"rgrpc","traceid":"77fc0a08975724beff160a095da08d7d","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.6 Safari/605.1.15","from":"tcp://127.0.0.1:41844","uri":"/cs3.storage.registry.v1beta1.RegistryAPI/ListStorageProviders","start":"25/Oct/2025:13:08:19 +0000","end":"25/Oct/2025:13:08:19 +0000","time_ns":4015152,"code":"PermissionDenied","time":"2025-10-25T13:08:19Z","message":"rpc error: code = PermissionDenied desc = auth: core access token is invalid"}
{"level":"error","service":"frontend","host.name":"opencloud-679444ff47-79d4k","pkg":"rhttp","time":"2025-10-25T13:08:19Z","message":"error: not found: gateway could not find space for ref=resource_id:{storage_id:\"9160e783-c388-4f99-9454-670a858b38f7\" opaque_id:\"82871925-9c76-43c0-86b9-aca5df7f96b3\" space_id:\"96458d93-d65f-4245-9b42-68751f04ab48\"} path:\".\""}

Setup

Running this in k8s with a HostPath mount for the data directory, but a pretty basic / minimal setup.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: opencloud
  labels:
    app: opencloud
spec:
  selector:
    matchLabels:
      app: opencloud
  replicas: 1
  template:
    metadata:
      labels:
        app: opencloud
    spec:
      containers:
        - name: opencloud
          image: opencloudeu/opencloud-rolling:latest
          env:
            - name: PROXY_HTTP_ADDR
              value: 0.0.0.0:9200
            - name: OC_URL
              value: https://opencloud.mydomain.com
          volumeMounts:
            - name: opencloud-config
              mountPath: /etc/opencloud
            - name: opencloud-data
              mountPath: /var/lib/opencloud
      volumes:
        - name: opencloud-config
          persistentVolumeClaim:
            claimName: opencloud-config
        - name: opencloud-data
          hostPath:
            path: /mnt/data/opencloud/

This is exposed through nginx-ingress, which I know is working because the download for logged-in users work too :-)

If there's anything else I can provide, please let me know!

tommyknows avatar Oct 25 '25 13:10 tommyknows

I cant reproduce :(

While I can see similar errors in my log:

opencloud-api-577b594789-jz5tj api {"level":"error","service":"sharing","host.name":"opencloud-api-577b594789-jz5tj","pkg":"rgrpc","traceid":"b7b270e7f1fa842ff0ff577d4e51aca1","user-agent":"grpc-go/1.76.0","from":"tcp://127.0.0.1:36828","uri":"/cs3.sharing.collaboration.v1beta1.CollaborationAPI/ListReceivedShares","start":"27/Oct/2025:10:41:26 +0000","end":"27/Oct/2025:10:41:26 +0000","time_ns":55610,"code":"PermissionDenied","time":"2025-10-27T10:41:26Z","message":"rpc error: code = PermissionDenied desc = auth: core access token is invalid"}
opencloud-api-577b594789-jz5tj api {"level":"error","service":"storage-shares","host.name":"opencloud-api-577b594789-jz5tj","pkg":"rgrpc","traceid":"b7b270e7f1fa842ff0ff577d4e51aca1","user-agent":"grpc-go/1.76.0","from":"tcp://127.0.0.1:42284","uri":"/cs3.storage.provider.v1beta1.SpacesAPI/ListStorageSpaces","start":"27/Oct/2025:10:41:26 +0000","end":"27/Oct/2025:10:41:26 +0000","time_ns":305482,"code":"PermissionDenied","time":"2025-10-27T10:41:26Z","message":"sharesstorageprovider: error calling ListReceivedSharesRequest: sharesstorageprovider: error calling ListReceivedSharesRequest: rpc error: code = PermissionDenied desc = auth: core access token is invalid"}
opencloud-api-577b594789-dqw2h api {"level":"error","service":"sharing","host.name":"opencloud-api-577b594789-dqw2h","pkg":"rgrpc","traceid":"5b3dfcfd7d22a7aaf4a64d2556716ba9","user-agent":"grpc-go/1.76.0","from":"tcp://127.0.0.1:37158","uri":"/cs3.sharing.collaboration.v1beta1.CollaborationAPI/ListReceivedShares","start":"27/Oct/2025:10:41:26 +0000","end":"27/Oct/2025:10:41:26 +0000","time_ns":153171,"code":"PermissionDenied","time":"2025-10-27T10:41:26Z","message":"rpc error: code = PermissionDenied desc = auth: core access token is invalid"}
opencloud-api-577b594789-dqw2h api {"level":"error","service":"storage-shares","host.name":"opencloud-api-577b594789-dqw2h","pkg":"rgrpc","traceid":"5b3dfcfd7d22a7aaf4a64d2556716ba9","user-agent":"grpc-go/1.76.0","from":"tcp://127.0.0.1:56690","uri":"/cs3.storage.provider.v1beta1.SpacesAPI/ListStorageSpaces","start":"27/Oct/2025:10:41:26 +0000","end":"27/Oct/2025:10:41:26 +0000","time_ns":537983,"code":"PermissionDenied","time":"2025-10-27T10:41:26Z","message":"sharesstorageprovider: error calling ListReceivedSharesRequest: sharesstorageprovider: error calling ListReceivedSharesRequest: rpc error: code = PermissionDenied desc = auth: core access token is invalid"}
opencloud-api-577b594789-dqw2h api {"level":"info","service":"proxy","proto":"HTTP/1.1","request-id":"opencloud-api-577b594789-dqw2h/y7jVx5HNW0-001048","traceid":"ba42f0dddef51ccb454aba46191578cb","remote-addr":"10.42.0.1","method":"GET","status":200,"path":"/remote.php/dav/public-files/DQfMcajTMFTAeCc/greg-rutkowski-alela-artful-provocateur-1500.jpg","duration":25.972519,"bytes":126773,"time":"2025-10-27T10:41:26Z","line":"github.com/opencloud-eu/opencloud/services/proxy/pkg/middleware/accesslog.go:34","message":"access-log"}
opencloud-api-577b594789-jz5tj api {"level":"info","service":"proxy","proto":"HTTP/1.1","request-id":"opencloud-api-577b594789-jz5tj/ggBAe27OOj-001040","traceid":"17170dff41db9115bf58d309fd1e2121","remote-addr":"10.42.0.1","method":"GET","status":200,"path":"/remote.php/dav/public-files/DQfMcajTMFTAeCc/greg-rutkowski-after-battle-final-last.jpg","duration":27.032996,"bytes":141174,"time":"2025-10-27T10:41:26Z","line":"github.com/opencloud-eu/opencloud/services/proxy/pkg/middleware/accesslog.go:34","message":"access-log"}
opencloud-api-577b594789-dqw2h api {"level":"info","service":"proxy","proto":"HTTP/1.1","request-id":"opencloud-api-577b594789-dqw2h/y7jVx5HNW0-001049","traceid":"3713c3eb7e48940b316566ef33400fbf","remote-addr":"10.42.0.1","method":"GET","status":200,"path":"/remote.php/dav/public-files/DQfMcajTMFTAeCc/greg-rutkowski-amonkhet-2.jpg","duration":26.957146,"bytes":108324,"time":"2025-10-27T10:41:26Z","line":"github.com/opencloud-eu/opencloud/services/proxy/pkg/middleware/accesslog.go:34","message":"access-log"}
opencloud-api-577b594789-jz5tj api {"level":"info","service":"proxy","proto":"HTTP/1.1","request-id":"opencloud-api-577b594789-jz5tj/ggBAe27OOj-001041","traceid":"fb6263f0b810362a1b1cacb4b3e6d397","remote-addr":"10.42.0.1","method":"GET","status":200,"path":"/remote.php/dav/public-files/DQfMcajTMFTAeCc/greg-rutkowski-ancient-greenwarden-1600.jpg","duration":28.773678,"bytes":171310,"time":"2025-10-27T10:41:26Z","line":"github.com/opencloud-eu/opencloud/services/proxy/pkg/middleware/accesslog.go:34","message":"access-log"}
opencloud-api-577b594789-dqw2h api {"level":"error","service":"sharing","host.name":"opencloud-api-577b594789-dqw2h","pkg":"rgrpc","traceid":"34f759994c080e126714d83ffe7dde5e","user-agent":"grpc-go/1.76.0","from":"tcp://127.0.0.1:37158","uri":"/cs3.sharing.collaboration.v1beta1.CollaborationAPI/ListReceivedShares","start":"27/Oct/2025:10:41:26 +0000","end":"27/Oct/2025:10:41:26 +0000","time_ns":108701,"code":"PermissionDenied","time":"2025-10-27T10:41:26Z","message":"rpc error: code = PermissionDenied desc = auth: core access token is invalid"}
opencloud-api-577b594789-dqw2h api {"level":"error","service":"storage-shares","host.name":"opencloud-api-577b594789-dqw2h","pkg":"rgrpc","traceid":"34f759994c080e126714d83ffe7dde5e","user-agent":"grpc-go/1.76.0","from":"tcp://127.0.0.1:56690","uri":"/cs3.storage.provider.v1beta1.SpacesAPI/ListStorageSpaces","start":"27/Oct/2025:10:41:26 +0000","end":"27/Oct/2025:10:41:26 +0000","time_ns":490583,"code":"PermissionDenied","time":"2025-10-27T10:41:26Z","message":"sharesstorageprovider: error calling ListReceivedSharesRequest: sharesstorageprovider: error calling ListReceivedSharesRequest: rpc error: code = PermissionDenied desc = auth: core access token is invalid"}
opencloud-api-577b594789-dqw2h api {"level":"info","service":"proxy","proto":"HTTP/1.1","request-id":"opencloud-api-577b594789-dqw2h/y7jVx5HNW0-001051","traceid":"6e1c21d2f896ba6e91506667ccc2a82d","remote-addr":"10.42.0.1","method":"GET","status":200,"path":"/remote.php/dav/public-files/DQfMcajTMFTAeCc/greg-rutkowski-angel-1500.jpg","duration":20.32549,"bytes":141067,"time":"2025-10-27T10:41:26Z","line":"github.com/opencloud-eu/opencloud/services/proxy/pkg/middleware/accesslog.go:34","message":"access-log"}

They do not prevent me from downloading a zip of the selected files.

I absolutely admit thata we should not log this as error ...

What does the browser console say? Which request fails?

butonic avatar Oct 27 '25 10:10 butonic

Appreciate the help! mmh okay so the logs might be a red herring 🤔 In the console I'm seeing two messages:

Failed to load resource: the server responded with a status of 404 ()

with the URL:

https://opencloud.mydomain.com/archiver?public-token=<sometoken>&id=9160e783-c388-4f99-9454-670a858b38f7$96458d93-d65f-4245-9b42-68751f04ab48!af311d60-94b8-4e0b-9ebe-f65d2ac12859&id=9160e783-c388-4f99-9454-670a858b38f7$96458d93-d65f-4245-9b42-68751f04ab48!9f4de7b4-aa21-44c5-b1a8-2836c0b6196d

Second message:

[Error] Error: archive could not be fetched
vt — FileSideBar-B_yfhUC-.mjs:1:1597
(anonymous function) — index.html-Rehgsan5.mjs:6:44237

	(anonymous function) (FileSideBar-B_yfhUC-.mjs:1:24118)

To me that's not saying much... 😅 but I hope this helps!

tommyknows avatar Oct 27 '25 21:10 tommyknows

archive could not be fetched indicates that creating the blob failed. We recently optimized this whole process via https://github.com/opencloud-eu/web/pull/1403, it could very well be that this also fixed your issue. It will be available with the next rolling release beginning next week.

2 more questions though:

  • is your link protected with a password?
  • how big are the files your trying to download?

JammingBen avatar Oct 28 '25 07:10 JammingBen

Thanks - I‘ll follow that and hope that it fixed the issue!

is your link protected with a password?

Yes - is there a way to create links without password protection? (i haven‘t really dug into this - is there a setting to allow the creation of links without passwords that I need to enable first?)

how big are the files your trying to download?

I‘ve tried with different files and sizes, but everything‘s been failing. I‘d say a few MBs. But i don‘t think that‘s the issue - with a logged in user i was able to download a whole directory, archived, at around 200MBs without an issue….

tommyknows avatar Oct 30 '25 10:10 tommyknows

Yes - is there a way to create links without password protection? (i haven‘t really dug into this - is there a setting to allow the creation of links without passwords that I need to enable first?)

You can run the server with this env to disable the password protection

OC_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD=false

saw-jan avatar Oct 31 '25 04:10 saw-jan

Thanks! I've retried it with a link without a password and I'm getting a download.zip file that's 246 bytes with the contents:

error:·not·found:·gateway·could·not·find·space·for·ref=resource_id:{storage_id:"9160e783-c388-4f99-9454-670a858b38f7"·opaque_id:"af311d60-94b8-4e0b-9ebe-f65d2ac12859"·space_id:"96458d93-d65f-4245-9b42-68751f04ab48"}·path:"."PK␅␆␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀

(this is the zip, displayed as text)

so, not really a success either 🤔

Note: behaviour generally seems different know - when downloading through a password-protected link I'm getting a file "archiver" that's 0 bytes. This is on the rolling image / 3.7.0.

tommyknows avatar Nov 03 '25 18:11 tommyknows

Note: behaviour generally seems different know - when downloading through a password-protected link I'm getting a file "archiver" that's 0 bytes.

Oh yeah, this I can actually reproduce with the latest version. There seems to be an issue on the web client because there is no url signing happening.

@butonic @rhafer How can the client retrieve a signing key on password-protected links? I tried using the base64-encoded password as basic auth header (just like we're doing it with e.g. webdav requests), but the server gives me a 401 error. And when using the signed URL, what should be given as OC-Credential when there is no username?

Thanks! I've retried it with a link without a password and I'm getting a download.zip file that's 246 bytes with the contents:

error:·not·found:·gateway·could·not·find·space·for·ref=resource_id:{storage_id:"9160e783-c388-4f99-9454-670a858b38f7"·opaque_id:"af311d60-94b8-4e0b-9ebe-f65d2ac12859"·space_id:"96458d93-d65f-4245-9b42-68751f04ab48"}·path:"."PK␅␆␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀

(this is the zip, displayed as text)

Despite what I've written above, it should work on public links without a password. So there is another issue, which seems more related to your setup IMO 🤔

JammingBen avatar Nov 04 '25 10:11 JammingBen

I've applied my k8s manifests with slight modifications to my local docker-desktop cluster and there I also can't reproduce the issue. I'm currently on holiday but will get back to this once I'm back - not sure what the issue is but since nobody can reproduce i don't think it's super urgent. Appreciate all the help so far and will get back to you as soon as possible!

tommyknows avatar Nov 06 '25 13:11 tommyknows

The download issue on password-protected links has been fixed via https://github.com/opencloud-eu/web/pull/1523. So from my perspective, everything should work as expect now. For that reason, I'm removing the p2 label (@db-ot fyi).

JammingBen avatar Nov 10 '25 13:11 JammingBen