Skip to content

[bug]: Plane One bundled proxy (proxy-commercial:v2.6.0) corrupts multipart POST /uploads → all uploads fail with InvalidAccessKeyId #9234

@alxwlw

Description

@alxwlw

Describe the bug

On a Plane One (Commercial) v2.6.0 self-host installed via prime-cli --behind-proxy (bundled MinIO), all file uploads fail — project covers, profile pictures, attachments. The browser performs an S3 presigned POST /uploads (multipart/form-data) and MinIO returns:

<Error><Code>InvalidAccessKeyId</Code><Message>The Access Key Id you provided does not exist in our records.</Message><BucketName>uploads</BucketName><Resource>/uploads</Resource></Error>

The credential in the presigned form is the correct MinIO root key, and mc / boto3 calls from inside the network authenticate fine. The failure happens only through the bundled proxy-commercial Caddy.

Root cause (bisected)

The same signed presigned POST:

Path Result
→ bundled MinIO directly (any Host, incl. the public domain) 204 No Content
→ bundled Caddy (proxy-commercial:v2.6.0) → MinIO (with or without an upstream reverse proxy; HTTP/1.1 and HTTP/2) 403 InvalidAccessKeyId

MinIO never logs the request as a PostPolicyBucket op in mc admin trace — it cannot parse the multipart form, falls through to header/query auth, finds no key, and 403s. So the bundled Caddy is mangling the multipart/form-data body (or its Content-Type/framing) on the /uploads route.

Ruled out, each verified independently: the Host header (MinIO accepts the public host directly → 204), the HTTP version (h1 and h2 both 403), and any upstream reverse proxy / WAF (reproduced by hitting the bundled Caddy directly on its :80 listener, no upstream in the path).

Relevant config

The prime-cli-generated Caddy routes uploads as:

(plane_proxy) {
    request_body {
        max_size {$FILE_SIZE_LIMIT}
    }
    ...
    reverse_proxy /{$BUCKET_NAME}   plane-minio:9000
    reverse_proxy /{$BUCKET_NAME}/* plane-minio:9000
    ...
}

($BUCKET_NAME=uploads.) A signed POST replayed straight to plane-minio:9000 succeeds; the identical POST through this Caddy 403s.

Steps to reproduce

  1. Install Plane One via prime-cli setup --behind-proxy (bundled MinIO).
  2. In the UI, create a project with a cover image (or upload a profile picture).
  3. The upload POST /uploads returns 403 InvalidAccessKeyId.

To confirm it is the proxy: mc share upload <alias>/uploads/test.jpg to mint a presigned POST, then run the resulting curl (a) against http://<minio>:9000204, and (b) against the public Plane URL → 403.

Expected behavior

Uploads through the bundled proxy succeed (204), the same as direct-to-MinIO.

Workaround

Route /uploads around the bundled Caddy — straight to MinIO — at the upstream reverse proxy (or any proxy that forwards the multipart body unmodified). That restores uploads.

Environment

  • Plane One (Commercial) v2.6.0, installed via prime-cli --behind-proxy
  • Bundled MinIO RELEASE.2025-09-07T16-13-09Z, bundled proxy makeplane/proxy-commercial:v2.6.0
  • Single-host Docker

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions