Mastodon instances that use S3-compatible object storage for media files may encounter the error “Object Storage Upload Failed” when users try to attach images, videos, or other files to posts. This error typically appears as a red banner in the web interface or as a logged failure in the Mastodon sidekiq jobs. The root cause is almost always a misconfiguration in the Mastodon environment variables that control S3 access or a network-level restriction blocking the upload request. This article explains the specific configuration values that must be correct, provides step-by-step instructions to verify and fix each setting, and covers related failure patterns such as timeouts and permission errors.
Key Takeaways: Fixing S3 Upload Failures in Mastodon
- S3_ENABLED=true: Must be set in the Mastodon environment to activate object storage instead of local disk.
- AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY: Provide the S3-compatible service credentials with write permissions to the bucket.
- S3_BUCKET name and S3_REGION: Must match the exact bucket name and region configured in your S3 provider.
Why Mastodon Fails to Upload Media to S3 Object Storage
Mastodon stores user-uploaded media such as profile pictures, header images, and post attachments. By default, Mastodon saves these files to the local filesystem. When you enable S3-compatible object storage, Mastodon uses the AWS SDK for Ruby to upload files to a remote bucket. The upload process involves several steps: the Mastodon web process receives the file, sidekiq processes the upload job, and the SDK sends a PUT request to the S3 endpoint. If any of the environment variables controlling this process are missing, incorrect, or misaligned with the S3 provider’s requirements, the upload fails.
The most common root causes are:
- Missing or incorrect S3_ENABLED: Mastodon ignores all S3 settings if this variable is not set to
true. - Wrong S3_PROTOCOL or S3_HOSTNAME: For non-AWS S3 providers like DigitalOcean Spaces or MinIO, you must set these to the correct endpoint URL.
- Bucket permissions: The IAM user or access key must have
s3:PutObjectands3:PutObjectAclpermissions on the bucket. - Network or firewall blocking: The Mastodon server must be able to reach the S3 endpoint over HTTPS on port 443.
Steps to Diagnose and Fix the S3 Upload Error in Mastodon
Follow these steps in order. Test after each change by uploading a small image file to any Mastodon post.
- Check the Mastodon environment file
SSH into your Mastodon server as the mastodon user. Open the.env.productionfile located in the Mastodon home directory, usually/home/mastodon/live/.env.production. Run:sudo -u mastodon nano /home/mastodon/live/.env.production. Verify that the following lines exist and are uncommented: - Confirm S3_ENABLED is set to true
Look for the lineS3_ENABLED=true. If it is missing or set tofalse, Mastodon will not use S3 at all and will attempt to save files locally, which may also fail if the local storage path is misconfigured. - Verify AWS credentials
Ensure these lines are present:AWS_ACCESS_KEY_ID=your-access-keyAWS_SECRET_ACCESS_KEY=your-secret-key
The access key must have write permissions to the S3 bucket. If you are unsure, generate a new key pair from your S3 provider’s control panel. - Set the correct bucket name and region
Check thatS3_BUCKET=your-bucket-namematches exactly the bucket you created. For region, useS3_REGION=us-east-1or the region your provider uses. DigitalOcean Spaces uses the regionnyc3orams3. - Configure S3 endpoint for non-AWS providers
If you use a provider other than AWS, you must set:S3_PROTOCOL=httpsS3_HOSTNAME=nyc3.digitaloceanspaces.com
Replace the hostname with your provider’s endpoint. For MinIO, use the IP or domain of your MinIO server. - Set S3_ALIAS_HOST if needed
If your S3 bucket is accessed through a custom domain or CDN, setS3_ALIAS_HOST=https://media.yourdomain.com. This tells Mastodon to serve media URLs from that domain instead of the direct S3 endpoint. - Restart Mastodon services
After saving the environment file, restart all Mastodon processes for the changes to take effect. Run:sudo systemctl restart mastodon-web mastodon-sidekiq mastodon-streaming - Test the upload
Log in to your Mastodon instance as an admin or regular user. Compose a new toot and attach an image file under 5 MB. If the upload succeeds, the error is resolved.
If Mastodon Still Shows Upload Failed After Configuration Changes
S3 bucket CORS configuration blocks uploads
Even with correct Mastodon settings, the S3 bucket itself may reject uploads due to missing or incorrect CORS headers. Log in to your S3 provider’s control panel and add the following CORS rule to the bucket:
[
{
"AllowedHeaders": [""],
"AllowedMethods": ["PUT", "POST", "GET", "HEAD"],
"AllowedOrigins": ["https://your-mastodon-instance.com"],
"ExposeHeaders": ["ETag"]
}
]
Replace the origin with your Mastodon instance domain. If you are testing locally, use http://localhost:3000.
Bucket policy denies PutObject for the access key
The IAM user or access key must have a policy that allows s3:PutObject. A typical policy looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::your-bucket-name/"
}
]
}
Attach this policy to the user associated with the access key. For DigitalOcean Spaces, use the Spaces access key with the appropriate permissions in the Spaces control panel.
Firewall or DNS blocks the S3 endpoint
From the Mastodon server, test connectivity to the S3 endpoint using curl. Run:curl -I https://nyc3.digitaloceanspaces.com
If the command hangs or returns a timeout, check your server’s firewall rules. Ensure outbound HTTPS traffic to the S3 endpoint IP range is allowed. Also verify that DNS resolution works for the hostname.
File size exceeds the S3 bucket limit or Mastodon limit
Mastodon has a default file size limit of 8 MB for attachments. Some S3 providers impose a lower limit. Check your provider’s documentation. You can adjust the Mastodon limit by setting MAX_IMAGE_SIZE and MAX_VIDEO_SIZE in the environment file, but the S3 provider must accept the larger size.
Mastodon S3 Configuration vs Local Storage: Key Differences
| Item | S3 Object Storage | Local Filesystem |
|---|---|---|
| Storage location | Remote bucket on S3-compatible provider | Local disk on the Mastodon server |
| Environment variable required | S3_ENABLED=true plus AWS credentials and endpoint | No S3 variables needed |
| Scalability | High; storage is independent of server disk | Limited by server disk capacity |
| Backup strategy | Provider-managed replication or separate backup bucket | Manual backup of the public/system directory |
| Upload failure cause | Misconfigured environment, bucket permissions, or network | Disk full, incorrect permissions on local directories |
| Typical fix | Verify S3_ENABLED, credentials, endpoint, and CORS | Free disk space or fix ownership of /home/mastodon/live/public/system |
Now you can resolve the “Object Storage Upload Failed” error by verifying each S3 environment variable in your Mastodon .env.production file, restarting the services, and confirming the bucket’s CORS and IAM policies allow write operations. If the problem persists, test network connectivity to the S3 endpoint and check the Mastodon sidekiq logs for detailed error messages using journalctl -u mastodon-sidekiq -n 50. For ongoing maintenance, monitor the bucket’s storage usage and set up lifecycle policies to delete old media files automatically.