問題 : 公開リンクでアクセスしてアップロードする場合だけ1GB超ファイルがアップできない
自宅に立てたNextCloudでフォルダを共有する際、共有リンク(公開リンク)からファイルをアップロードしてもらおうとするとアップロードのエラーが発生した。
いくつかのファイルがアップロードできませんでした
アップロード中のエラー、ステータスコード 413
調べてみると以下のような挙動であることがわかった。
- 1GB以上のファイルを公開リンクからアップロードしようとするとエラーが発生する。
- 1GB未満は問題なくアップできる。
- 作成権限のある通常ユーザーがログインしている場合は、容量に関わらずアップロードできる。
- アップロードのプログレスバーは100%近くまで問題なく進み、しばらく止まってエラーが発生する。
NextCloudの管理画面からログを見てみると、次のようなエラーが発生していた。

環境
- コンテナ管理 : Docker Compose
- Webサーバー : Apache (NextCloud内蔵)
- Nextcloud : 31.0.6
- PHPバージョン : 8.3.23
- DB : MariaDB 11.8.2
- リバースプロキシ : Nginx Proxy Manager v2.12.3
- SSL : Let’s Encrypt(NPMから設定)
- OS : Ubuntu 24.04.2 LTS
- Docker : 28.1.1
- Portainer : 2.27.6 LTS
試したけどダメだったこと
NextCloudの設定に不備がないか?→該当するような設定項目なし
初歩的な設定ミスだが、まずはNextCloud自体の設定で何か制限されていないかを確認した。
NextCloudでは、ユーザーごとの保存容量の設定や、チームフォルダの容量の設定をすることができる。しかしそれらの容量にはまだゆとりがあり、そもそも通常ユーザーでログインしている場合は今回は問題なくアップできていたため、原因からは外れた。
匿名ユーザーのアップロードサイズの設定も探したが、そのような設定項目は見つからなかった。
マウント先の容量不足?→十分ある

こちらも初歩的なミスだがドライブの容量不足を疑った。
というのも、このサーバーはデータの保存先を外付けHDDにして運用しているのだが、以前外付けHDDケースの電源がいつの間にか落ちていて保存先が変わっていたことがあったからだ。
外付けHDDを/mnt/xxxxxxxにマウントし、/mnt/xxxxxxx/data:/var/www/html/dataのように設定するとデータだけ外付けHDDに保存することができるが、HDDが外れた際には実際の/mnt/xxxxxxx/dataに保存されてしまうのだ。内蔵SSDが圧迫されて容量がなくなりアップロードエラーが出たことで初めて気がついたということがあった。
しかし今回はHDDも正常にマウントされており、容量も問題なかった。
tmpフォルダなども確認したが、いずれも問題なさそうだった。
PHPのupload_max_filesize→512MBだけどこれが原因ではない
NextCloudのファイルの制限について検索すると、1番にこれが原因として出てきた。
私の環境でも「管理者設定」→「システム」で状態を見てみると、PHPの最大アップロードサイズ: 512 MBとなっていた。

この設定を変えるために、以下の設定をymlに書いたり、iniで変更したりした。
upload_max_filesize = 20G #試しに20GBまでアップできるようにしてみる
post_max_size = 20G #関係ないかもしれないがここも上げてみる
memory_limit = 1G #メモリもたくさん使えるようにする
max_input_time = 3600 #アップロード中にタイムアウトしないようにする
max_execution_time = 3600 #同上
しかしこの設定は効果はなく、512MBのままでも本来はファイルリクエストで大きなデータもアップできそうだった。
Cloudflareの100MB制限?→使っていない
Cloudflareの場合、初期値では100MBのアップロードサイズの制限があるという記事もいくつかヒットした。
しかし私の環境は自宅サーバーなので該当しない。
NPMのclient_max_body_size→効果なし

NPMにも影響しそうな設定があったので
client_max_body_size 200G;
のように変えてみたが、こちらも解決には至らなかった。
解決策 : Apacheの制限を緩める
NextCloudでは大きなファイルをアップロードする際に、チャンクに分割してアップする機能がある。ログイン中の通常ユーザーがアップロードする際は、この機能によって小さなチャンクごとにアップされる。
しかし匿名ユーザーが公開リンクからアップロードする際は、ファイル全体を一度にアップロードするようになっているようだった。
これだけだと問題ないのだが、NextCloudは内部でApacheが動作しており、Apacheでは約1GBのサイズ制限が設定されていることに原因があった。
それまではApacheはLimitRequestBodyに制限はなかったが、2.4.54からは、LimitRequestBodyに約1GBの制限が導入された。このバージョンのApacheを内蔵するNextCloud 24以降では、匿名アップロード時のチャンク化未対応と重なり、1GB以上のアップロードができなくなっていたのだった。
1GBの制限を外すために.ymlに以下のように追記することであっけなく解決した。
services:
....
nextcloud2_app:
image: nextcloud
container_name: nextcloud2_app
restart: always
environment:
MYSQL_DATABASE: xxxxxxx
....
MYSQL_HOST: xxxxxxx
APACHE_BODY_LIMIT: 0 #←これを追加
本来はnextcloud-apache.confもしくは.htaccessの設定を変えるのが正しいのかもしれないが、上記の手っ取り早い方法でも今のところちゃんと動いている。
参考記事
https://github.com/nextcloud/docker/issues/1796
https://help.nextcloud.com/t/requests-entity-too-large-with-nextcloud-apache-docker-image/177125