You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Worklogs export download links use http:// even with MINIO_ENDPOINT_SSL=1 set #9550
Related to #5827, same root issue but specific to the Worklogs/Timesheets export feature.
We're self-hosting Plane Commercial (Docker Compose via prime-cli), behind Cloudflare Tunnel so TLS ends at Cloudflare and the internal proxy traffic is plain HTTP. Tested this on both v2.5.3 and v3.0.1, same result on both.
Every download link from Worklogs export (Project Settings > Worklogs > Download, plus the Previous Downloads list) comes back as an http:// presigned URL, like:
Since the site itself is https, Chrome silently blocks these as insecure downloads. No error, no toast, the click just does nothing. Confirmed the file itself is fine, curl -L on the same url works and pulls the CSV down no problem, so it's really just the scheme on the link that's wrong.
We set MINIO_ENDPOINT_SSL=1 and AWS_S3_ENDPOINT_URL=https://, which per storage.py is supposed to force https on generated presigned urls when behind a proxy like ours. Verified both vars are actually set inside the api and worker containers, and the app confirms it can reach the bucket fine through the new url on startup (Checking bucket... Bucket 'uploads' exists.).
Everything else that goes through S3Storage seems to respect this fine based on the code, but Worklogs export specifically doesn't. Freshly generated exports (checked via server request logs, not cached) still come back http:// even with the fix applied and containers freshly restarted. Seems like Worklogs/Timesheets export must be running separate code from the normal S3Storage.generate_presigned_url path, maybe since it's an enterprise only feature.
Anyone know if Worklogs export url generation is a separate code path, and if so can it get the same SSL override support?
Your hunch about this being a separate code path is right. Traced it, and the reason everything else respects MINIO_ENDPOINT_SSL is that everything else goes through S3Storage, which checks the flag directly at apps/api/plane/settings/storage.py:41:
and AWS_S3_URL_PROTOCOL comes from the scheme of WEB_URL, not from MINIO_ENDPOINT_SSL and not from AWS_S3_ENDPOINT_URL. apps/api/plane/settings/common.py:313-316:
That is the only definition and the only use of AWS_S3_URL_PROTOCOL in the repo, which is what makes this a one-line problem.
The URL you pasted confirms the path. .replace('/uploads', '') strips the bucket back off the custom domain leaving http://<domain>/, and boto3 then appends /<bucket>/<key>, producing exactly http://<domain>/uploads/<uuid>.csv?X-Amz-.... The Worklogs view itself is not in this repo, but it clearly lands on the same settings pair.
Worth noting the default self-host config guarantees this: deployments/cli/community/variables.env:15 hardcodes WEB_URL=http://${APP_DOMAIN}. Anyone terminating TLS at a proxy gets http: here no matter what they set MINIO_ENDPOINT_SSL or AWS_S3_ENDPOINT_URL to. Setting WEB_URL=https://<domain> should work around it for you in the meantime.
Fix is to make this line agree with the check storage.py already makes:
Ran the settings logic in isolation across the realistic configurations to check nothing else moves:
config
current
patched
TLS at proxy, internal http, MINIO_ENDPOINT_SSL=1
http://plane.example.com/
https://plane.example.com/
compose default, flag unset
http://plane.example.com/
unchanged
WEB_URL already https
https://plane.example.com/
unchanged
plain http deploy, MINIO_ENDPOINT_SSL=0
http://192.168.1.50/
unchanged
Only someone who explicitly asked for SSL sees a change.
Two caveats. ExporterHistory.url is a stored URLField written once at export_task.py:118, so existing rows keep their old links and only new exports come back correct. And this looks like the same root cause as #5827, though I cannot test the images and attachments surface to confirm.
There is already a # TODO: Change the upload_to_s3 function to use the new storage method at export_task.py:41. Routing export through S3Storage is the proper fix and would delete this whole class of divergence, but it is a much bigger change, so I have kept this to the one line that makes the two paths agree. Opening a PR now, happy to take it the other way instead if maintainers prefer.
Activity
Hayyan612 commentedon Sep 16, 2026
Your hunch about this being a separate code path is right. Traced it, and the reason everything else respects
MINIO_ENDPOINT_SSLis that everything else goes throughS3Storage, which checks the flag directly atapps/api/plane/settings/storage.py:41:Export never touches
S3Storage. It builds its own boto3 client atapps/api/plane/bgtasks/export_task.py:65-73:and
AWS_S3_URL_PROTOCOLcomes from the scheme ofWEB_URL, not fromMINIO_ENDPOINT_SSLand not fromAWS_S3_ENDPOINT_URL.apps/api/plane/settings/common.py:313-316:That is the only definition and the only use of
AWS_S3_URL_PROTOCOLin the repo, which is what makes this a one-line problem.The URL you pasted confirms the path.
.replace('/uploads', '')strips the bucket back off the custom domain leavinghttp://<domain>/, and boto3 then appends/<bucket>/<key>, producing exactlyhttp://<domain>/uploads/<uuid>.csv?X-Amz-.... The Worklogs view itself is not in this repo, but it clearly lands on the same settings pair.Worth noting the default self-host config guarantees this:
deployments/cli/community/variables.env:15hardcodesWEB_URL=http://${APP_DOMAIN}. Anyone terminating TLS at a proxy getshttp:here no matter what they setMINIO_ENDPOINT_SSLorAWS_S3_ENDPOINT_URLto. SettingWEB_URL=https://<domain>should work around it for you in the meantime.Fix is to make this line agree with the check
storage.pyalready makes:Ran the settings logic in isolation across the realistic configurations to check nothing else moves:
MINIO_ENDPOINT_SSL=1http://plane.example.com/https://plane.example.com/http://plane.example.com/WEB_URLalready httpshttps://plane.example.com/MINIO_ENDPOINT_SSL=0http://192.168.1.50/Only someone who explicitly asked for SSL sees a change.
Two caveats.
ExporterHistory.urlis a storedURLFieldwritten once atexport_task.py:118, so existing rows keep their old links and only new exports come back correct. And this looks like the same root cause as #5827, though I cannot test the images and attachments surface to confirm.There is already a
# TODO: Change the upload_to_s3 function to use the new storage methodatexport_task.py:41. Routing export throughS3Storageis the proper fix and would delete this whole class of divergence, but it is a much bigger change, so I have kept this to the one line that makes the two paths agree. Opening a PR now, happy to take it the other way instead if maintainers prefer.fix(storage): honour MINIO_ENDPOINT_SSL when building export presigne…