Images are randomly deleted from server

I’ve got a bizarre problem with a website I’m working on.

Recently, when anyone uploads images to the site, some time later (maybe an hour, sometimes several hours) one or more images disappear from the server. They still show up in the Media Library, and all the other sizes created by WordPress are still on the server. But whatever size is being used on the page (usually the full size image, but not always) randomly gets deleted.

If I replace the missing file via FTP, they tend to disappear again fairly quickly (sometimes minutes, sometimes hours later).

I’ve tried removing any plugins recently installed. No luck.

I’ve even migrated the site to a completely different server. Oddly, it seemed to work at first. For several days, I had the site on the new server and no images disappeared. But then, once I updated the DNS settings to point the domain over, then they started to disappear.

Neither hosting company had any clue what could be causing it.

Have you ever seen a problem like this? Any idea what function I can look for that could be deleting images at random?

Update: I eventually found the problem was related to a plugin called CyberSEO Lite. Ever since I removed it, no more images have disappeared.

3 Answers
3

Obviously, I imagine you already checked cron jobs.

No one can tell you, but whenever you have an issue and you’re wondering “what the hell is interacting with my system?” and that part that’s problematic (in your case, the deletion of the image) has actions inside of it, we can see what called that specific deletion. So let’s see how this applies in your case.

An image is a post. When it gets deleted, unless something bad happens, you can safely say that wp_delete_post will be used and inside of this function, we have the earliest action we can hook into before_delete_post:

add_action( 'before_delete_post', function( $postid ) {
    $past_backtrace = get_option( 'backtrace_for_deletion', [] );
    $current_backtrace = debug_backtrace();

    $past_backtrace[] = json_encode( $current_backtrace );
    update_option( 'backtrace_for_deletion', $past_backtrace );
});

We basically want to see what called this deletion, so let’s make it a bit prettier:

    $backtraces = get_option( 'backtrace_for_deletion' );
    foreach( $backtraces as $backtrace ) {
        ?>
        <pre>
        <?php
            print_r( json_decode( $backtrace ) );
            echo '-----------------------------------------------------------------------------------';
        ?>
        </pre>
        <?php
    }

This isn’t exactly the best view, but it gives you the information.

A few points:

  1. Third item is always where the deletion is called from, it’ll give you the exact file name and line of what called the deletion.
  2. If this doesn’t work, then I advise you turn server file logging on, as well as database logging and look at the queries.

Leave a Comment