Ao configurar o Mastodon com um backend de armazenamento compatível com S3, você pode encontrar o erro ‘Media could not be stored’ quando os usuários tentam enviar imagens, vídeos ou outros arquivos. Este problema geralmente ocorre devido a permissões de bucket S3 mal configuradas, URLs de endpoint incorretas ou variáveis de ambiente ausentes na configuração do Mastodon. Este artigo explica as causas raiz desse erro e fornece instruções claras e passo a passo para resolvê-lo, tanto para AWS S3 quanto para serviços compatíveis como DigitalOcean Spaces ou MinIO.
Principais conclusões: Corrigindo o armazenamento de mídia S3 no Mastodon
- Variável de ambiente S3_ALIAS_HOST: Deve corresponder exatamente à URL do endpoint do bucket para evitar falhas de roteamento DNS.
- Configuração CORS do bucket: Necessária para uploads baseados em navegador; regras CORS ausentes bloqueiam uploads de mídia silenciosamente.
- Permissões do usuário IAM: O usuário S3 precisa das ações s3:PutObject, s3:GetObject e s3:ListBucket no bucket.
Por que o Mastodon não consegue armazenar mídia no S3
O Mastodon usa a biblioteca Active Storage do Ruby on Rails para lidar com uploads de arquivos. Quando configurado para S3, ele depende das variáveis de ambiente definidas no arquivo .env.production ou no ambiente Docker. O erro ‘Media could not be stored’ aparece quando o Mastodon falha ao enviar o arquivo para o bucket S3 durante a operação de gravação.
As três causas raiz mais comuns são:
Configuração incorreta do endpoint do bucket
O Mastodon espera que a variável S3_ALIAS_HOST corresponda ao endpoint público do seu bucket. Se você usar um endpoint diferente para as requisições de API versus a URL pública, a chamada de upload falha. Por exemplo, o DigitalOcean Spaces usa nyc3.digitaloceanspaces.com para chamadas de API, mas requer um CDN ou domínio personalizado para o alias host.
Permissões de bucket ausentes ou incorretas
O usuário IAM ou as chaves de acesso que o Mastodon usa devem ter permissões explícitas para gravar objetos no bucket. Se a política permitir apenas operações de leitura, os uploads falham silenciosamente. Além disso, o bucket não deve ter uma política que negue acesso público ao objeto após o upload.
Headers CORS ausentes para uploads diretos
O Mastodon pode ser configurado para fazer upload de arquivos diretamente do navegador para o S3 usando URLs pré-assinadas. Este método requer que o bucket S3 tenha uma configuração CORS que permita requisições do seu domínio Mastodon. Sem isso, o upload do navegador falha e o Mastodon registra o erro ‘Media could not be stored’.
Passos para corrigir o erro de armazenamento de mídia S3 no Mastodon
Siga estes passos em ordem. Teste após cada passo enviando uma pequena imagem na interface web do Mastodon.
- Verifique as variáveis de ambiente S3 no .env.production
Abra o arquivo.env.productiondo Mastodon. Confirme que estas variáveis estão configuradas corretamente:S3_ENABLED=trueS3_BUCKET=nome-do-seu-bucketAWS_ACCESS_KEY_ID=sua-chave-de-acessoAWS_SECRET_ACCESS_KEY=sua-chave-secretaS3_REGION=us-east-1(ou a região do seu bucket)S3_PROTOCOL=httpsS3_HOSTNAME=nyc3.digitaloceanspaces.com(para Spaces) ous3.amazonaws.com(para AWS)S3_ALIAS_HOST=seu-dominio-personalizado.comou a URL direta do bucket. Para AWS, useseu-bucket.s3.amazonaws.com. - Teste o acesso S3 com AWS CLI
Instale o AWS CLI no servidor Mastodon. Executeaws s3 ls s3://nome-do-seu-bucket --endpoint-url https://nyc3.digitaloceanspaces.com. Se falhar, suas credenciais ou endpoint estão errados. Corrija as variáveis e execute novamente. - Atualize a configuração CORS do bucket
Crie um arquivo chamadocors.jsoncom este conteúdo:{ "CORSRules": [ { "AllowedOrigins": ["https://seu-dominio-mastodon.com"], "AllowedMethods": ["GET", "PUT", "POST"], "AllowedHeaders": ["*"], "ExposeHeaders": ["ETag"] } ] }
Aplique usando o AWS CLI:aws s3api put-bucket-cors --bucket nome-do-seu-bucket --cors-configuration file://cors.json --endpoint-url https://nyc3.digitaloceanspaces.com. Substitua a URL do endpoint pela do seu provedor. - Verifique as permissões do usuário IAM
No seu provedor de nuvem, verifique se o usuário IAM associado às chaves de acesso tem pelo menos estas permissões no bucket:s3:PutObject,s3:GetObject,s3:ListBucket,s3:DeleteObject. Anexe uma política como esta:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:ListBucket", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::nome-do-seu-bucket", "arn:aws:s3:::nome-do-seu-bucket/*" ] } ] } - Reinicie os serviços do Mastodon
Após fazer as alterações, reinicie todos os processos do Mastodon:systemctl restart mastodon-web mastodon-sidekiq mastodon-streaming. Para configurações Docker, executedocker-compose restart. - Teste o upload
Faça login no Mastodon como administrador. Vá em Preferências > Perfil e envie uma nova imagem de avatar. Se o erro persistir, verifique os logs do Mastodon:journalctl -u mastodon-web -n 50. Procure por linhas contendo ‘ActiveStorage::IntegrityError’ ou ‘S3’.
Se o Mastodon ainda mostrar o erro de armazenamento S3
Mesmo após aplicar a correção principal, alguns casos específicos podem fazer o erro reaparecer. Abaixo estão cenários específicos e suas resoluções.
Incompatibilidade de região do bucket
Se você definir S3_REGION com um valor que não corresponde à região real do bucket, o AWS SDK pode rotear a requisição para o endpoint errado. Para DigitalOcean Spaces, a região faz parte da URL do endpoint (ex.: nyc3). Defina S3_REGION com esse valor. Para AWS, use o código de região exato, como us-west-2.
Problemas de certificado SSL em domínio personalizado
Se você usar um domínio personalizado para S3_ALIAS_HOST, o domínio deve ter um certificado SSL válido. O Mastodon usa HTTPS para todas as requisições S3. Se o certificado for autoassinado ou expirado, o upload falha. Use um certificado do Let’s Encrypt ou do CDN do seu provedor de nuvem.
Tamanho do arquivo excede o limite do bucket
Alguns provedores compatíveis com S3 têm um limite de tamanho de arquivo padrão de 100 MB. Se um usuário enviar um vídeo maior que isso, o Mastodon registra o erro ‘Media could not be stored’. Verifique a documentação do seu provedor para o tamanho máximo de objeto. Para AWS S3, o limite é de 5 TB, mas sua política de bucket pode restringi-lo.
Comparação de configuração: Armazenamento S3 vs Local no Mastodon
| Item | Armazenamento S3 | Armazenamento Local |
|---|---|---|
| Variáveis de configuração | S3_ENABLED, S3_BUCKET, chaves de acesso AWS, S3_HOSTNAME, S3_ALIAS_HOST | Nenhuma variável adicional; arquivos armazenados em /public/system |
| Escalabilidade | Armazenamento ilimitado, replicação automática entre regiões | Limitado pelo espaço em disco do servidor; backup manual necessário |
| Latência para usuários | Depende do CDN ou região do bucket; pode ser global | Local ao servidor; pode ser lento para usuários remotos |
| Manutenção | Requer monitoramento de políticas do bucket, CORS e chaves de acesso | Requer limpeza de disco e scripts de backup |
| Custo | Pague por GB armazenado e por requisição; pode ser maior em escala | Custo único de hardware; sem taxas por requisição |
O erro ‘Media could not be stored’ no Mastodon é quase sempre uma incompatibilidade de configuração entre as variáveis de ambiente do Mastodon e as configurações do bucket S3. Verificando a URL do endpoint, as regras CORS e as permissões IAM, você pode resolver o problema em menos de 15 minutos. Após corrigir, teste com um upload de arquivo pequeno. Se os problemas persistirem, verifique os logs do Mastodon em busca de erros do ActiveStorage. Para configurações avançadas, considere usar um CDN como Cloudflare na frente do seu bucket S3 para reduzir a latência e adicionar uma camada extra de cache.