Orphaned Files: Root Cause & Fix Proposal

John Holland website — johnholland.com.au

📅 30 May 2026 🔍 Read-only investigation ⚠️ 34 sensitive PDFs still publicly accessible
⚠️
Immediate concern

The client deleted files from Strapi's Media Library believing they were removed. They are not — 34 PDFs and 303 images remain publicly accessible via direct URL, including sensitive community agreements and environmental monitoring reports.

What Is Happening

The client deletes a file from Strapi's Media Library. The file disappears from the Media Library interface — so it looks like it's gone. But if someone knows the direct URL, they can still open the file in their browser as if nothing happened.

2,936
Files physically on disk
2,599
Files tracked in Strapi
337
Orphaned files (deleted from Strapi but still on disk)

Of those 337 orphaned files, 34 are PDFs — many of which are sensitive documents (community agreements, environmental licences, monitoring reports).


Why Is This Happening

The site was originally built using AWS S3 as the file storage provider. At some point, it was migrated to local disk storage on the server. The files were physically moved to the server — but the database was never updated to reflect the change.

What the database currently says about file storage

Provider recorded in DB Number of files Status
aws-s3 1,008 files Old provider Mismatch
strapi-provider-upload-aws-s3-custom 522 files Old provider Mismatch
local 39 files Current provider ✓

The actual server config uses provider: 'local' — but 1,530 files in the DB still say they belong to S3.

This mismatch is the root cause. Here is exactly what happens step by step when the client deletes a file:

What Strapi does when you click "Delete" in the Media Library

🗂️
Step 1 — Strapi looks up the file record in the database It reads the file's details — including which storage provider uploaded it. For older files, the DB says provider: aws-s3.
🪣
Step 2 — Strapi calls the S3 provider to delete the file Wrong provider Because the DB says "aws-s3", Strapi sends a delete request to Amazon S3 — not to the local disk. The file was already moved off S3, so S3 either returns "not found" or deletes nothing. Either way, the file on the server's disk is never touched.
🗑️
Step 3 — Strapi removes the database record Succeeds This always works. The file disappears from the Media Library UI. From the client's point of view, the file is gone.
📂
Step 4 — Physical file remains on disk Never deleted Because Strapi went to S3 (not local disk) to delete the file, the physical file at /opt/johnholland/uploads/ is untouched. Anyone who knows the URL can still access it.

In plain English

Strapi is looking in the wrong place when it tries to delete a file. It goes to S3 (the old storage), not the local disk (the current storage). So the Media Library shows the file as deleted, but it's still sitting on the server — publicly accessible.


Sensitive PDFs Still Publicly Accessible

These 34 PDFs are confirmed orphaned — not in Strapi, but still downloadable via direct URL:

📄USC_Community_Agreement_EPL_Park_Road_Rev_D
📄USC_Community_Agreement_EPL_AWRC_working_hours_Rev_C (×2)
📄USC_Community_Agreement_EPL_AWRC_working_hours_Rev_D
📄USC_Community_Agreement_EPL_AWRC_working_hours_Rev_E
📄USC_Community_Agreement_EPL_AWRC_working_hours_Rev_F
📄USC_Community_Agreement_EPL_AWRC_working_hours_Rev_G
📄USC_EPL_21800_Approved_and_In_Force
📄USC_EPL_21800_LVA_Notice_1637064
📄USC_EPL_21800_Monitoring_Data (multiple dates)
📄USC_EPL_21800_PIRMP_Extract (×2)
📄USC_EPL_21800_Premise_Maps (multiple revisions)
📄USC_EPL_21800_Premises_Map (multiple revisions)
📄USC_Environmental_Protection_License_21800
📄USC_Licence_No_21800
📄SGP_RPT_059198/059205/059214 (2022 reports)
📄jh_modern_slavery_fy2020

Proposed Fix

There are three steps to fully resolve this — an immediate action, a database correction, and a process improvement.

1
Immediately delete the 34 orphaned PDFs from disk

We already know exactly which 34 PDF files are orphaned. We can delete them directly from the server with a single script. This stops any further access to sensitive documents right away.

⏱ ~15 minutes ✅ No risk — files are already removed from Strapi Needs client confirmation first
2
Delete remaining 303 orphaned image/SVG files from disk

The other orphaned files (mostly images) should also be cleaned up. These were deleted from the Media Library by the client but never removed from disk. We can run the same cleanup script for all 337 orphaned files at once.

⏱ ~30 minutes including review ⚠️ Confirm list before deleting
3
Update the database — correct the provider field for all files

Update all file records in the DB from aws-s3 / strapi-provider-upload-aws-s3-custom to local. This fixes the root cause — future deletes from the Media Library will now correctly remove the physical file from disk.

⏱ ~1 hour (including backup & testing) ⚠️ Requires DB backup before running 🔴 Prevents this from recurring

Summary

QuestionAnswer
Why can people still access deleted files?The database told Strapi to delete from S3. Strapi never deleted the file from the server's disk.
Is this a Strapi bug?Partially — Strapi should surface a failure when the provider mismatch occurs. But the primary cause is the incomplete S3 → local migration.
How many files are affected?337 files total — 34 PDFs, 303 images/SVGs.
Can we fix it without downtime?Yes — deleting files and updating the DB does not require any service restart.
Will this happen again after the fix?No — once the provider field is corrected (Step 3), future Media Library deletes will work correctly.