Eu descobri o problema depois de depurar e tentar mais algumas soluções. Aparentemente, a regra 301 é analisada pelo nginx antes de qualquer manipulação de bloco de localização, portanto, a 301 sempre foi a primeira e a última regra a ser aplicada a todas as URLs. Eu criei um bloco de localização "pega-tudo" separado que serve o 301 se nenhum outro local corresponder, então minha configuração final agora se parece com isso:
server {
listen 80;
listen [::]:80;
server_name stats.example.com;
root /usr/share/nginx/html;
# ACME challenge configuration for Letsencrypt
location ^~ /.well-known/acme-challenge/ {
try_files $uri =404;
}
location / {
return 301 https://stats.example.com$request_uri;
}
}
Agora consegui emitir o certificado usando o Certbot.