How to Resolve Mastodon ‘Object Storage Upload Failed’ on S3
🔍 WiseChecker

How to Resolve Mastodon ‘Object Storage Upload Failed’ on S3

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:PutObject and s3:PutObjectAcl permissions 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.

  1. Check the Mastodon environment file
    SSH into your Mastodon server as the mastodon user. Open the .env.production file 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:
  2. Confirm S3_ENABLED is set to true
    Look for the line S3_ENABLED=true. If it is missing or set to false, 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.
  3. Verify AWS credentials
    Ensure these lines are present:
    AWS_ACCESS_KEY_ID=your-access-key
    AWS_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.
  4. Set the correct bucket name and region
    Check that S3_BUCKET=your-bucket-name matches exactly the bucket you created. For region, use S3_REGION=us-east-1 or the region your provider uses. DigitalOcean Spaces uses the region nyc3 or ams3.
  5. Configure S3 endpoint for non-AWS providers
    If you use a provider other than AWS, you must set:
    S3_PROTOCOL=https
    S3_HOSTNAME=nyc3.digitaloceanspaces.com
    Replace the hostname with your provider’s endpoint. For MinIO, use the IP or domain of your MinIO server.
  6. Set S3_ALIAS_HOST if needed
    If your S3 bucket is accessed through a custom domain or CDN, set S3_ALIAS_HOST=https://media.yourdomain.com. This tells Mastodon to serve media URLs from that domain instead of the direct S3 endpoint.
  7. 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
  8. 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.