Diagnosing Mattermost File Upload Failures: 413 and 500 Errors
Step‑by‑step diagnostic guide for Mattermost file upload failures (HTTP 413/500), with cause table, ordered checks, config‑level fixes, and escalation triggers.
16 Jun 2026, 13:11 UTC

Recognizable condition
Users report that file attachments either return HTTP 413 Payload Too Large or a generic HTTP 500 Internal Server Error. Small files (e.g., < 1 MB) upload successfully, while larger files fail consistently.
Cause / diagnostic quick‑reference table
| Observed symptom | Likely cause | Primary log indicator |
|---|---|---|
| 413 on any file > X MB | Server‑wide MaxFileSize or per‑channel/team limit exceeded | "level":"error","msg":"file size exceeds limit" |
| 500 on large files only | Disk full, Postgres connection pool exhaustion, or TLS timeout during multipart streaming | "level":"error","msg":"failed to write file" or "pq: sorry, too many clients already" |
| 403 on specific extensions | File‑type policy blocks the MIME type | "level":"warn","msg":"file type not allowed" |
| 400 on any upload | Malformed multipart request or parser mis‑configuration | "level":"error","msg":"multipart parse error" |
Ordered diagnostic checks
- Confirm the exact HTTP status – capture the response with browser dev‑tools or
curl -v -F "files=@test.pdf" https://mattermost.example.com/api/v4/files. Note the status code and any JSON error body. - Inspect server logs – on the Mattermost host (requires root or the service account):
Look for the log lines shown in the table above.grep -i -e 'upload' -e 'file size' -e 'multipart' /var/log/mattermost/mattermost.log | tail -30 - Verify the configured upload ceiling – in
config.json(or System Console → Environment → File Storage):"FileSettings": { "MaxFileSize": 52428800, "EnableFileAttachments": true, "DriverName": "local" }MaxFileSizeis in bytes (50 MB in the example). Also check per‑channel overrides viaChannelSettings.MaxFileSizeif set. - Test the threshold – create a file just under the limit and one just over it:
The under‑limit file should returndd if=/dev/zero of=under.bin bs=1M count=49 # 49 MB dd if=/dev/zero of=over.bin bs=1M count=51 # 51 MB curl -v -F "files=@under.bin" https://mattermost.example.com/api/v4/files curl -v -F "files=@over.bin" https://mattermost.example.com/api/v4/files201; the over‑limit file should return413with a matching log entry. - Check storage health – run
df -h /var/opt/mattermost/data(or the mount point used by the file driver). Ensure at least 10 % free space and no inode exhaustion (df -i). - Validate Postgres connectivity – from the Mattermost host:
Watch forpsql "postgres://mmuser:password@dbhost:5432/mattermost?sslmode=disable" -c "SELECT 1;"too many clientsor timeout errors that appear only under load. - Review TLS / proxy timeouts – if a reverse proxy (nginx, HAProxy, AWS ALB) sits in front, verify
client_max_body_size(nginx) or equivalent is ≥MaxFileSizeand that proxy read/write timeouts exceed the expected upload duration (e.g., 300 s).
Fixes tied to findings
- 413 – limit too low: increase
FileSettings.MaxFileSizeinconfig.json(or via System Console) and restart Mattermost (systemctl restart mattermost). Ensure the reverse proxy allows the same size. - 500 – disk full: free space on the storage volume, then restart Mattermost. If using S3 driver, verify bucket quota and IAM permissions.
- 500 – Postgres pool exhaustion: raise
SqlSettings.MaxOpenConnsandMaxIdleConnsinconfig.json(typical values 30/10 for medium instances) and restart. - 500 – TLS / proxy timeout: adjust proxy timeouts (nginx:
proxy_read_timeout 300s; proxy_send_timeout 300s;) and reload the proxy. - 403 – file‑type block: add the missing MIME type to
FileSettings.AllowedFileTypes(comma‑separated list) or set"AllowAnyFileType": truetemporarily for testing. - 400 – multipart parse error: ensure the client sends proper
multipart/form-datawith afilesfield; if using a custom client, match the field name exactly.
Escalation criteria
Escalate to the platform team or Mattermost support when:
- All configuration limits are correct, storage and DB are healthy, yet 500 persists on files < 10 MB.
- Log entries show
panicor stack traces from the Go runtime. - Multiple unrelated services (e.g., websocket, search) degrade simultaneously, indicating a host‑level issue.
Limitations & verification
This guide covers server‑side configuration and infrastructure causes. Client‑side network throttling, antivirus interference, or browser‑specific multipart bugs are out of scope. After applying a fix, verify by uploading a file at 90 % of the new limit and confirming a 201 Created response and a log line "msg":"file uploaded".
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.