Is there an existing issue for this?
Current behavior
[Bug]: Mixed Content Error - MinIO presigned upload URLs use internal Docker hostname instead of external domain
Is there an existing issue for this?
Yes, related issues exist: #5827 and #6624 — but they remain unresolved.
Current Behavior
When Plane is deployed behind an HTTPS reverse proxy (Traefik/Caddy) with MinIO running as an internal Docker service, file uploads fail with a mixed content error in the browser:
Mixed Content: The page at 'https://my-plane-instance.example.com/...' was loaded over HTTPS,
but requested an insecure XMLHttpRequest endpoint 'http://plane-minio:9000/uploads'.
This request has been blocked; the content must be served over HTTPS.
The browser developer tools show the blocked request URL as:
http://plane-minio:9000/uploads
This makes it impossible to create projects, since Plane requires a cover image upload during project creation.
Expected Behavior
The presigned upload URL returned to the browser should use the external HTTPS domain (configured via AWS_S3_CUSTOM_DOMAIN) instead of the internal Docker hostname plane-minio:9000.
Steps to Reproduce
- Deploy Plane using Docker Compose behind an HTTPS reverse proxy (Traefik, Caddy, Nginx)
- MinIO running internally as
plane-minio:9000
- Set
AWS_S3_CUSTOM_DOMAIN=my-plane-instance.example.com/uploads
- Try to upload a cover image or file attachment
- Browser blocks the request:
http://plane-minio:9000/uploads → mixed content error
Environment
- Deployment: Docker Compose with Traefik/Caddy reverse proxy
- HTTPS: Yes (SSL terminated at reverse proxy)
- MinIO: Internal Docker service (
plane-minio:9000)
Relevant environment variables:
AWS_S3_ENDPOINT_URL=http://plane-minio:9000
AWS_S3_BUCKET_NAME=uploads
AWS_S3_CUSTOM_DOMAIN=my-plane-instance.example.com/uploads
Root Cause Analysis
Plane generates presigned URLs using the AWS_S3_ENDPOINT_URL value (http://plane-minio:9000) as the hostname. The AWS_S3_CUSTOM_DOMAIN variable is respected when displaying already-uploaded files, but is not used when generating presigned upload URLs that are returned to the browser.
This is a fundamental problem for any HTTPS deployment where MinIO is not directly exposed to the internet — which is the recommended and most common self-hosted setup.
Proposed Fix
One of the following solutions would resolve this issue:
Option 1: Use AWS_S3_CUSTOM_DOMAIN as the hostname for presigned upload URLs (not just for read URLs). The proxy already handles routing /uploads/ requests to MinIO internally.
Option 2: Add a dedicated environment variable (e.g. AWS_S3_UPLOAD_BASE_URL or MINIO_EXTERNAL_ENDPOINT) that explicitly overrides the hostname used in presigned upload URLs sent to the browser, while keeping AWS_S3_ENDPOINT_URL for internal server-to-MinIO communication.
Option 3: Allow project creation without requiring a cover image upload (make cover image optional or use a default).
Additional Context
This issue affects all self-hosted deployments behind HTTPS reverse proxies — which is essentially every production deployment. The Plane proxy container already includes logic to route /uploads/ requests to MinIO, so Option 1 should be straightforward to implement.
Related GitHub issues:
Steps to reproduce
- Deploy Plane using Docker Compose behind an HTTPS reverse proxy (Traefik, Caddy, Nginx)
- MinIO running internally as
plane-minio:9000
- Set
AWS_S3_CUSTOM_DOMAIN=my-plane-instance.example.com/uploads
- Try to upload a cover image or file attachment
- Browser blocks the request:
http://plane-minio:9000/uploads → mixed content error
Environment
Production
Browser
Google Chrome
Variant
Self-hosted
Version
latest
Is there an existing issue for this?
Current behavior
[Bug]: Mixed Content Error - MinIO presigned upload URLs use internal Docker hostname instead of external domain
Is there an existing issue for this?
Yes, related issues exist: #5827 and #6624 — but they remain unresolved.
Current Behavior
When Plane is deployed behind an HTTPS reverse proxy (Traefik/Caddy) with MinIO running as an internal Docker service, file uploads fail with a mixed content error in the browser:
The browser developer tools show the blocked request URL as:
This makes it impossible to create projects, since Plane requires a cover image upload during project creation.
Expected Behavior
The presigned upload URL returned to the browser should use the external HTTPS domain (configured via
AWS_S3_CUSTOM_DOMAIN) instead of the internal Docker hostnameplane-minio:9000.Steps to Reproduce
plane-minio:9000AWS_S3_CUSTOM_DOMAIN=my-plane-instance.example.com/uploadshttp://plane-minio:9000/uploads→ mixed content errorEnvironment
plane-minio:9000)Relevant environment variables:
Root Cause Analysis
Plane generates presigned URLs using the
AWS_S3_ENDPOINT_URLvalue (http://plane-minio:9000) as the hostname. TheAWS_S3_CUSTOM_DOMAINvariable is respected when displaying already-uploaded files, but is not used when generating presigned upload URLs that are returned to the browser.This is a fundamental problem for any HTTPS deployment where MinIO is not directly exposed to the internet — which is the recommended and most common self-hosted setup.
Proposed Fix
One of the following solutions would resolve this issue:
Option 1: Use
AWS_S3_CUSTOM_DOMAINas the hostname for presigned upload URLs (not just for read URLs). The proxy already handles routing/uploads/requests to MinIO internally.Option 2: Add a dedicated environment variable (e.g.
AWS_S3_UPLOAD_BASE_URLorMINIO_EXTERNAL_ENDPOINT) that explicitly overrides the hostname used in presigned upload URLs sent to the browser, while keepingAWS_S3_ENDPOINT_URLfor internal server-to-MinIO communication.Option 3: Allow project creation without requiring a cover image upload (make cover image optional or use a default).
Additional Context
This issue affects all self-hosted deployments behind HTTPS reverse proxies — which is essentially every production deployment. The Plane proxy container already includes logic to route
/uploads/requests to MinIO, so Option 1 should be straightforward to implement.Related GitHub issues:
Steps to reproduce
plane-minio:9000AWS_S3_CUSTOM_DOMAIN=my-plane-instance.example.com/uploadshttp://plane-minio:9000/uploads→ mixed content errorEnvironment
Production
Browser
Google Chrome
Variant
Self-hosted
Version
latest