Submission & Galley File Upload Errors: Fixing fuv & Permissions
Comprehensive troubleshooting manual for file upload errors in OJS. Learn how to resolve PHP upload limits, fix outside-webroot permissions, and bypass MIME-type blocks.
Real Problem
Authors attempting to submit manuscripts or production editors uploading PDF galleys encounter upload failures caused by PHP size restrictions, MIME-type rejections, or broken directory permissions.
Practical Solution
Align upload_max_filesize and post_max_size in php.ini, configure allowed MIME types in OJS workflow settings, repair Linux ownership on files_dir, and resolve CSRF token expiration bugs.
The Multi-Stage Lifecycle of an OJS File Upload
When an author or editor uploads a manuscript, figure, or PDF galley in Open Journal Systems, the file passes through a multi-tier pipeline before resting securely on disk:
1. Browser Client: JavaScript verifies file size and extension.
2. Web Server Gateway: Nginx/Apache enforces client_max_body_size limits.
3. PHP Runtime: PHP buffers the stream into /tmp based on upload_max_filesize and post_max_size.
4. OJS Validation: OJS inspects the MIME type using finfo or mime_content_type.
5. Disk Storage: OJS moves the binary from /tmp to /var/ojs_files/journals/X/articles/Y/.
A failure at any point in this sequence causes a generic "Upload failed" notice in the editorial dashboard.
Step 1: Aligning PHP Runtime Directives
The most frequent cause of upload failure is default PHP limits restricting files to 2MB. Open your PHP-FPM configuration:
nano /etc/php/8.1/fpm/php.ini
Adjust the following directives:
upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M
max_execution_time = 180
max_input_time = 180
Remember that post_max_size must be equal to or greater than upload_max_filesize. Restart PHP-FPM:
systemctl restart php8.1-fpm
Step 2: Nginx Web Server Body Size Tuning
If using Nginx, client_max_body_size defaults to 1MB. Any upload exceeding this will immediately return HTTP 413 Request Entity Too Large.
In /etc/nginx/nginx.conf or your specific server block:
client_max_body_size 64M;
Reload Nginx:
nginx -s reload
Step 3: Correcting Linux Directory Permissions
If PHP receives the file but cannot write to the storage repository, it throws a fatal warning. Ensure proper ownership:
chown -R www-data:www-data /var/ojs_files
chmod -R 750 /var/ojs_files
Also verify that PHP's temporary directory is writable:
chmod 1777 /tmp
Step 4: Investigating the "fuv" (File Upload Validation) Bug
In OJS 3.3 and 3.4, some users encounter the "fuv" validation modal when uploading DOCX or PDF files. This occurs when PHP's finfo extension detects a MIME type that conflicts with the file extension.
Ensure the php-fileinfo module is compiled and enabled:
apt install php8.1-fileinfo
systemctl restart php8.1-fpm
Step-by-Step Action Plan
Check php.ini Upload Size Limits
Increase upload_max_filesize = 64M and post_max_size = 64M in both CLI and PHP-FPM php.ini configurations.
Verify files_dir Writable Permissions
Confirm that /var/ojs_files has 750 permissions and is owned by the web server user (www-data or nginx).
Inspect Web Server client_max_body_size
In Nginx, ensure client_max_body_size 64M is declared inside the http or server configuration block.
Review OJS Submission File Genres
In Journal Settings > Workflow > Submission > Components, verify that Article Text, Supplementary Files, and Galley genres are active.
Resolve ModSecurity / WAF False Positives
Inspect Web Application Firewall logs to ensure security rules are not flagging large PDF binary uploads.
Questions People Usually Ask
What does the cryptic "fuv" error mean in OJS?
The "fuv" (File Upload Validation) error occurs when the uploaded file fails client-side or server-side MIME-type inspection, or when the temporary upload directory in PHP lacks write access.
Why does an upload fail immediately at 100% completion?
When an upload fails at 100%, the browser successfully transmitted the data, but the server failed during the final save step—usually because files_dir is not writable or post_max_size was exceeded.
Can authors upload files larger than 100MB in OJS?
Yes, provided php.ini (upload_max_filesize and post_max_size), Nginx (client_max_body_size), and PHP memory_limit are configured to accommodate the larger threshold.
Authors Unable to Upload Submissions?
AcademiaTech audits upload pipelines, tunes PHP execution limits, and resolves file permission blocks across all OJS workflow stages.