-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
Description
What features would you like to see added?
Description:
I am attempting to configure LibreChat to use Hetzner Object Storage (S3-compatible) as the CDN file strategy.
Hetzner (like MinIO and older Ceph setups) requires Path-Style Access (e.g., https://endpoint/bucket/key) because their SSL certificates do not support the Virtual-Hosted-Style subdomains (e.g., https://bucket.endpoint/key) that the AWS SDK defaults to.
Currently, packages/api/src/cdn/s3.ts hardcodes the S3Client configuration and ignores any forcePathStyle setting. This makes it impossible to use LibreChat with these providers without patching the code at runtime.
Steps to Reproduce:
- Configure
.envwith S3-compatible credentials that require path-style access (e.g., Hetznerfsn1):AWS_REGION="fsn1" AWS_ENDPOINT_URL="https://fsn1.your-objectstorage.com" AWS_BUCKET_NAME="my-uuid-bucket" AWS_ACCESS_KEY_ID="xxx" AWS_SECRET_ACCESS_KEY="xxx" # This variable is currently ignored by LibreChat: AWS_FORCE_PATH_STYLE="true"
- Configure
librechat.yaml:fileStrategy: "s3" - Attempt to upload a file (e.g., an avatar or image).
Actual Behavior:
The upload fails with a 401 Unauthorized or SignatureDoesNotMatch error.
The browser receives a presigned URL in Virtual-Hosted style:
https://my-uuid-bucket.fsn1.your-objectstorage.com/images/...
This URL fails because the SSL certificate for *.your-objectstorage.com does not cover the nested bucket subdomain, or the provider rejects the signature structure.
Expected Behavior:
LibreChat should respect an environment variable (e.g., AWS_FORCE_PATH_STYLE) to enable Path-Style access, generating URLs like:
https://fsn1.your-objectstorage.com/my-uuid-bucket/images/...
More details
Root Cause Analysis:
In packages/api/src/cdn/s3.ts, the initializeS3 function initializes the client with region and endpoint but omits forcePathStyle.
Proof of Fix (Verified in Container):
I ran the following Node.js script inside the LibreChat container using the exact same AWS SDK present in node_modules.
- Test A (Default/Current Behavior): Fails with 401/Signature Error.
- Test B (With forcePathStyle): Succeeds immediately.
const { S3Client, PutObjectCommand } = require("@aws-sdk/client-s3");
// Successful Configuration
const config = {
region: process.env.AWS_REGION,
endpoint: process.env.AWS_ENDPOINT_URL,
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
},
// This is the missing key in LibreChat:
forcePathStyle: true
};
const client = new S3Client(config);
// This works perfectly when forcePathStyle is true
const cmd = new PutObjectCommand({
Bucket: process.env.AWS_BUCKET_NAME,
Key: "test_upload.txt",
Body: "Test"
});
client.send(cmd).then(() => console.log("Success"));Proposed Solution:
Update packages/api/src/cdn/s3.ts to include forcePathStyle in the config object:
const config = {
region,
// Add this line:
forcePathStyle: process.env.AWS_FORCE_PATH_STYLE === 'true',
...(endpoint ? { endpoint } : {}),
};Which components are impacted by your request?
General
Pictures
No response
Code of Conduct
- I agree to follow this project's Code of Conduct