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
Copy file name to clipboardExpand all lines: apps/docs/content/docs/en/platform/self-hosting/object-storage.mdx
+19-24Lines changed: 19 additions & 24 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -78,7 +78,6 @@ cat > /tmp/cors.json <<'EOF'
78
78
"AllowedOrigins": ["https://sim.yourdomain.com"],
79
79
"AllowedMethods": ["GET", "PUT"],
80
80
"AllowedHeaders": ["*"],
81
-
"ExposeHeaders": ["ETag"],
82
81
"MaxAgeSeconds": 3600
83
82
}
84
83
]
@@ -91,10 +90,6 @@ for name in workspace-files knowledge-base execution-files chat-files \
91
90
done
92
91
```
93
92
94
-
<Callouttype="warn">
95
-
`ExposeHeaders`**must** include `ETag`. Files larger than 50 MB use multipart uploads, and the browser reads each part's `ETag` to complete the upload — CORS hides the header otherwise and large uploads fail at the final step.
96
-
</Callout>
97
-
98
93
Set `AllowedOrigins` to your exact Sim origin (scheme + host, no trailing slash). Add every origin users reach Sim from, including an apex/`www` pair if both are live.
Header names must be listed individually — GCS CORS matches `responseHeader` entries exactly and does not support wildcards like `x-goog-meta-*`. `ETag` is required because large-file multipart uploads read each part's `ETag`from the browser, and CORS hides the header otherwise.
317
+
Header names must be listed individually — GCS CORS matches `responseHeader` entries exactly and does not support wildcards like `x-goog-meta-*`. `x-goog-if-generation-match` makes small-file uploads create-only; Sim obtains multipart ETags from GCS during completion rather than exposing them to the browser.
323
318
</Callout>
324
319
325
320
</Step>
@@ -467,25 +462,25 @@ The same browser-reachability and CORS requirements apply.
467
462
</Tab>
468
463
</Tabs>
469
464
470
-
## Configure temporary upload cleanup
465
+
## Configure incomplete multipart cleanup
471
466
472
-
Sim stages every direct upload under the `upload-sessions/` prefix before promoting it to its final,
473
-
immutable object key. Apply the cleanup policy to **every** purpose-specific bucket or container
474
-
configured above:
467
+
Sim uploads directly to a create-only final object key and keeps upload-session state in PostgreSQL.
468
+
The cleanup cron claims expired sessions before deleting an uploaded object or aborting its provider
469
+
multipart state. Configure provider lifecycle cleanup as a second line of defense for multipart
470
+
state that outlives its database row:
475
471
476
-
- On AWS S3 and Google Cloud Storage, expire objects under `upload-sessions/` after two days and
477
-
abort incomplete multipart uploads after two days.
478
-
- On Azure Blob, expire committed blobs under `upload-sessions/` after two days. Azure automatically
479
-
removes uncommitted blocks after seven days.
480
-
- For an S3-compatible provider, configure both rules when its lifecycle implementation supports
481
-
them. Check the provider's documentation because lifecycle feature support varies.
472
+
- On AWS S3 and Google Cloud Storage, abort incomplete multipart uploads after two days on every
473
+
purpose-specific bucket.
474
+
- Azure automatically removes uncommitted blocks after seven days.
475
+
- For an S3-compatible provider, configure incomplete-multipart cleanup when its lifecycle
476
+
implementation supports it. Check the provider's documentation because support varies.
482
477
483
-
The two-day window exceeds the 24-hour upload-token lifetime and leaves time to retry completion.
484
-
Do not apply this prefix rule to final objects outside `upload-sessions/`.
478
+
The provider window should exceed the 24-hour upload-session lifetime so an in-progress completion
479
+
can still recover. Do not add an object-expiration rule for final upload keys.
485
480
486
481
<Callouttype="warning">
487
-
Configure both expiration and incomplete-multipart cleanup where available. Expiring staged
488
-
objects alone does not necessarily remove abandoned multipart parts.
482
+
Object expiration and incomplete-multipart cleanup are different lifecycle operations. Configure
483
+
the incomplete-multipart operation; expiring objects does not remove abandoned multipart parts.
Copy file name to clipboardExpand all lines: apps/docs/content/docs/en/platform/self-hosting/troubleshooting.mdx
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -193,7 +193,7 @@ Both pods must have `REDIS_URL`. On Helm they share one Secret, so setting it un
193
193
194
194
The bucket's CORS policy does not allow your Sim origin. Uploads go directly from the browser to object storage via presigned `PUT`, so server-side configuration being correct is not enough.
195
195
196
-
If small uploads succeed but files over 50 MB fail at the last step, `ETag` is missing from the CORS exposed headers — multipart uploads read it from the browser. See [Object Storage](/platform/self-hosting/object-storage).
196
+
If small uploads succeed but files over 50 MB fail during completion, check the app logs for the provider's part-listing request. The server completes multipart uploads from provider-authoritative state; for S3, its identity needs `s3:ListMultipartUploadParts`. See [Object Storage](/platform/self-hosting/object-storage).
Copy file name to clipboardExpand all lines: apps/docs/content/docs/en/platform/self-hosting/verify.mdx
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,7 +18,7 @@ Run this after a first install, after an upgrade, and after a restore. Each step
18
18
| 4 | Open the same workflow in a second browser window and edit | Cross-replica collaboration | With >1 replica this needs [Redis](/platform/self-hosting/redis)|
19
19
| 5 | Paste a model API key in settings and run a two-block workflow | Execution engine, credential encryption, outbound network | App logs; check `ENCRYPTION_KEY` is set and outbound egress is allowed |
20
20
| 6 | Upload a small file in Files | File storage end to end | With object storage configured: presigned URL + bucket CORS. On local disk: the upload proxies through the app |
21
-
| 7 | Upload a file larger than 50 MB | Multipart upload path (object storage only) |Confirm `ETag` is in the bucket's CORS exposed headers|
21
+
| 7 | Upload a file larger than 50 MB | Multipart upload path (object storage only) |Check app logs for provider part-listing or completion errors|
22
22
| 8 | Create a knowledge base and upload a PDF | Document parsing, embeddings, pgvector | Needs a hosted embedding provider — see below |
23
23
| 9 | Invite a teammate from workspace settings | Email delivery | App logs for the mailer; see [Email](/platform/self-hosting/email)|
24
24
| 10 | Connect an integration account | OAuth configuration | Redirect URI mismatch → see [Integrations & OAuth](/platform/self-hosting/integrations-oauth)|
@@ -72,7 +72,7 @@ All six should be present on Compose: `simstudio`, `realtime`, `db`, `redis`, `c
72
72
73
73
**Step 5 fails — execution errors.** Check outbound connectivity to the model provider, then the app logs. If the error is about decrypting a credential, `ENCRYPTION_KEY` differs from the one that encrypted it.
74
74
75
-
**Step 6 or 7 fails.** With object storage configured, a CORS error in the browser console means the bucket policy does not allow your Sim origin; step 7 failing while step 6 passes specifically means `ETag` is missing from the exposed headers. On local-disk storage there is no CORS involved — uploads proxy through the app, so look at the app logs and the proxy body-size limit instead.
75
+
**Step 6 or 7 fails.** With object storage configured, a CORS error in the browser console means the bucket policy does not allow your Sim origin or the signed upload headers. If step 7 fails only during completion, check the app logs and verify the server identity can list multipart parts (for S3, `s3:ListMultipartUploadParts`). On local-disk storage there is no CORS involved — uploads proxy through the app, so look at the app logs and the proxy body-size limit instead.
76
76
77
77
**Step 8 fails — knowledge base upload errors.** Knowledge bases need a hosted embedding provider — OpenAI, Azure OpenAI, or Gemini. There is no local embedding backend. If a key is set, check pgvector is installed on the database.
0 commit comments