Shared hosting FTP deployment fails after upload: checks that find the fault
By Daniel Brooks Published 10 min read
On this page (9 sections)
- The short version
- What a completed FTP transfer proves
- Shared hosting FTP deployment fails after upload: check the path first
- Check ownership and permissions with SSH or the file manager
- Prove the uploaded file matches your local copy
- Read cache headers instead of guessing the lifetime
- Check PHP errors and server logs
- Use staging and safer deployment methods
- Questions people still ask
In short: The upload finished, but the site may still read another file, reject the file, serve a cached response or hit a PHP error. Check the document root first, then ownership and permissions, file integrity, headers and logs.
Part of our guide on fix audio driver windows 11
| Common file mode | 644, if your host permits it |
|---|---|
| Common folder mode | 755, if your host permits it |
| Cache lifetime | Check headers and CDN settings |
| FTP control connection | Usually port 21 |
| Safer transfer choices | SFTP or FTPS |
The short version
- Confirm the control panel's document root before moving any files.
- Use SSH commands such as ls -l and stat to inspect ownership, mode and timestamps.
- Compare checksums, not just file size, to prove the server copy matches your local file.
- Inspect Cache-Control, Age and ETag headers before deciding a cache caused the problem.
- Use staging, SFTP or FTPS, and an atomic move for safer repeat deployments.
What a completed FTP transfer proves
Your FTP client says Transfer complete, but the browser still shows yesterday's page. That result feels contradictory until you separate the transfer from the web request.
FTP confirms the client sent data and the server accepted the transfer. It doesn't prove the file is in the document root, readable by the web process, free from corruption or absent from a cache.
Check the URL's document root in your hosting panel. A file in your FTP login folder can sit outside public_html, www or htdocs, depending on the host.
Treat the browser response as a separate test. Request the exact URL, inspect its headers, then check server logs if the response is wrong. If that sounds like your situation, read up on registry edit stops working after saving changes next.
Shared hosting FTP deployment fails after upload: check the path first
Open the hosting panel and find Domains, Websites or Document Root. Record the directory assigned to the affected domain and subdomain.
In cPanel, open Domains and read the Document Root value. In Plesk, open Websites & Domains, choose the domain and inspect Hosting Settings. Other panels use similar domain settings.
Compare that path with the folder shown in your FTP client. Upload index.html or index.php into the assigned root, not merely into the first folder shown after login. We cover bat file continue after error on windows in its own article.
Check filename case too. Linux treats Index.php, index.php and INDEX.PHP as different files, while your local computer might hide the mistake.
- Find the domain's document root in the control panel.
- Open the same path in FTP or the panel's file manager.
- Confirm the changed file has the expected name and extension.
- Request the exact URL in a private browser window.
- Check rewrite rules if the URL reaches a different file.
Check ownership and permissions with SSH or the file manager
A web process can read a file only when its account and mode allow access. Ownership models differ, so don't assume FTP and PHP use the same Unix user.
Some hosts run both services under your account. Others use suEXEC or suexec, or place PHP in a PHP-FPM pool with a separate user. Ask support which account serves your domain if the panel doesn't show it. People in this spot often ask about how full is my computer storage as well.
With SSH, move into the document root and inspect the path: cd ~/public_html followed by ls -l index.php and stat index.php. A result such as -rw-r--r-- 1 alice users 4281 Mar 8 14:20 index.php shows the mode, owner, group, size and modification time.
The first field gives the mode. The next name is the owner, followed by the group. rw-r--r-- commonly maps to 644, so the owner can write while others can read. Directories also need execute permission to be traversed.
Use find . -maxdepth 2 -type d -printf '%M %u:%g %p\n' and find . -maxdepth 2 -type f -printf '%M %u:%g %p\n' to spot an outlier. Your host may restrict these format options. There is more on clean windows installer folder in a separate guide.
Don't run chown or broad recursive chmod commands without host guidance. A safe correction might be chmod 644 index.php, but ownership changes often require support or a specific account name.
Without SSH, open the panel's file manager, right-click the file and choose Permissions or Change Permissions. Look for an owner field if available. Use the host's reset-permissions tool, or send support the path and requested URL.
ls -l index.phpshows mode, owner, group, size and date.stat index.phpgives detailed metadata for the exact file.- A usual starting point is 644 for files and 755 for directories.
- Your host may require different modes for scripts, private folders or uploads.
- Ask support to confirm the PHP-FPM or suexec user before changing ownership.
- SSH exposes the exact owner and mode
- The file manager helps when SSH is unavailable
- Support can confirm the server account safely
- Some shared plans hide ownership details
- Incorrect recursive commands can break unrelated folders
Prove the uploaded file matches your local copy
File size and modification time can reveal a failed upload, but they don't prove identical content. A retry can preserve the size while changing bytes. For the detail, see our notes on fix windows waking from sleep.
Create a checksum locally with sha1sum index.php or md5sum index.php. SHA-1 is useful for an accidental-transfer check; neither hash protects against a deliberate attacker.
Download the server copy into a temporary directory, then calculate the same hash: curl -u 'user:password' -o /tmp/index.php https://example.com/index.php followed by sha1sum /tmp/index.php. Avoid putting credentials in shell history when possible.
A public URL can return cached or rewritten content, so compare the downloaded bytes with care. Use the FTP client's download function when you need the raw remote file, then hash that download.
Look at the FTP log for lines such as 150 Opening data connection, 226 Transfer complete and a matching byte count. A 426 Connection closed, retry notice, timeout or smaller byte count points to an incomplete transfer.
Upload to a temporary filename such as index.php.new, download it for the checksum, then rename it after verification. This keeps visitors away from a half-written file.
- Run
sha1sumormd5sumon the local file. - Download the remote file with curl or the FTP client.
- Run the same checksum on the downloaded copy.
- Compare the complete hash strings.
- Re-upload through SFTP or FTPS if the hashes differ.
Read cache headers instead of guessing the lifetime
A stale response can come from the browser, a host page cache, a CDN or application code. The exact lifetime depends on the host and CDN configuration.
Run curl -I https://example.com/ and inspect Cache-Control, Age, ETag, Last-Modified, Via and any CDN header. Cache-Control: max-age=3600 permits caching for 3,600 seconds, while an Age value shows how long a shared cache has held its response.
Repeat the request with a cache-busting query only as a diagnostic: curl -I 'https://example.com/?check=20250308'. A fresh response doesn't prove the normal URL is fresh, but differing headers reveal cache behavior.
In browser developer tools, open Network, reload the page, select the document request and read Response Headers. Compare a private window or another network if the response differs.
Use the control panel's cache purge button only after recording the headers. Check the CDN dashboard for its cache rules and purge controls. If no purge exists, ask the host which layer serves the response.
| Header | What it tells you | Where to inspect |
|---|---|---|
| Cache-Control | Allowed caching and max-age | curl or browser Network panel |
| Age | Seconds held by a shared cache | curl or browser Network panel |
| ETag | Version identifier for conditional requests | curl or browser Network panel |
| Last-Modified | Server's reported file time | curl or browser Network panel |
Check PHP errors and server logs
A new PHP file can load as a 500 response when its syntax, extension or dependency is wrong. The browser may show only a blank page, so read the server log.
In cPanel, open Metrics, Errors, or use the File Manager to inspect public_html/error_log. Some hosts place PHP logs under a domain-specific logs folder. Plesk commonly exposes logs through Websites & Domains, Logs, or files under /var/www/vhosts/system/example.com/logs/, if shell access permits.
Run tail -n 50 error_log from the document root when SSH is available. Search for PHP Fatal error, Permission denied, File not found and Allowed memory size. Match the timestamp to your test request.
Don't enable detailed errors for public visitors on a live site. Use the panel's PHP error-log setting, a staging domain or support's diagnostic tool instead.
Test .htaccess carefully if Apache returns 500. Rename it briefly, request the page, then restore it immediately. This can disable redirects, access rules and HTTPS handling.
Use staging and safer deployment methods
SFTP transfers files through SSH, usually on port 22, and encrypts credentials and content. FTPS adds TLS to FTP and commonly uses an explicit TLS connection on port 21.
Choose SFTP when your host provides SSH access. Choose FTPS when the host documents it and your client supports certificate checking. These methods reduce interception risk and give clearer transfer failures than plain FTP.
A small staging workflow needs only four steps. Upload the changed files to a staging subdomain, run a smoke test, create a dated backup, then move the verified files into the live root.
For an atomic move, upload a release directory such as releases/2025-03-08, verify checksums and permissions, then point a symlink named current at it if your host permits symlinks. Shared plans often restrict this, so ask support before relying on it.
If symlinks aren't allowed, keep the old folder, rename the verified staging folder into place during a quiet period and retain the backup. Test the home page, login, forms and assets after the move.
- Create a staging subdomain in the control panel.
- Upload with SFTP or FTPS into its document root.
- Test pages, PHP actions, assets and redirects.
- Back up the live folder and move the verified release.
- Keep the previous release for a quick rollback.
Follow the path, ownership, integrity, headers and logs in that order. Use staging with SFTP or FTPS once the cause is fixed, so the next deployment is easier to verify.
Questions people still ask
Why does my FTP client report success while the site shows old content?
The client confirms the transfer, not the URL's response. Check the domain's document root, then inspect the requested response headers and server log.
What ownership and permissions should I use?
Many Linux hosts start with 644 for files and 755 for folders, but the correct owner and PHP execution model vary. Check with ls -l or the file manager, then ask support before changing ownership.
How do I measure the cache lifetime?
Run curl -I https://example.com/ and read Cache-Control and Age. Confirm the CDN's cache rule in its dashboard. The host and CDN decide the actual behavior.
How can I prove a transfer was complete?
Download the remote file, run sha1sum or md5sum locally and remotely, and compare the hashes. Check the client log for a final 226 Transfer complete line and matching byte count.
Should I keep using plain FTP?
Use SFTP when SSH is available, or FTPS when your host documents it. Both protect credentials and content in transit better than plain FTP.