Skip to content

[bug]: Mixed Content Error - MinIO presigned upload URLs use internal Docker hostname instead of external domain #8881

@markusthiel

Description

@markusthiel

Is there an existing issue for this?

  • I have searched the existing issues

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

  1. Deploy Plane using Docker Compose behind an HTTPS reverse proxy (Traefik, Caddy, Nginx)
  2. MinIO running internally as plane-minio:9000
  3. Set AWS_S3_CUSTOM_DOMAIN=my-plane-instance.example.com/uploads
  4. Try to upload a cover image or file attachment
  5. 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

  1. Deploy Plane using Docker Compose behind an HTTPS reverse proxy (Traefik, Caddy, Nginx)
  2. MinIO running internally as plane-minio:9000
  3. Set AWS_S3_CUSTOM_DOMAIN=my-plane-instance.example.com/uploads
  4. Try to upload a cover image or file attachment
  5. Browser blocks the request: http://plane-minio:9000/uploads → mixed content error

Environment

Production

Browser

Google Chrome

Variant

Self-hosted

Version

latest

Metadata

Metadata

Assignees

Labels

planesync issues to Plane🐛bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions