# Retry Emails That Failed to Send

> Keeps emails that fail because of a temporary mail server problem and tries to send them again up to three times over the following half hour.

- Type: PHP
- Runs: Run everywhere
- Category: [Email](https://wpide.com/library/category/email/)
- Tags: email, reliability, cron
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/email-retry-failed/

## Code

```php
$wpide_retry_state = new stdClass();
$wpide_retry_state->running = false;

add_action( 'wp_mail_failed', function ( $error ) use ( $wpide_retry_state ) {
    $data = (array) $error->get_error_data();

    if ( $wpide_retry_state->running || empty( $data['to'] ) || ! empty( $data['attachments'] ) ) {
        return;
    }

    $queue   = (array) get_option( 'wpide_mail_retry', array() );
    $queue[] = array(
        'to'       => $data['to'],
        'subject'  => isset( $data['subject'] ) ? $data['subject'] : '',
        'message'  => isset( $data['message'] ) ? $data['message'] : '',
        'headers'  => isset( $data['headers'] ) ? $data['headers'] : array(),
        'attempts' => 0,
    );
    update_option( 'wpide_mail_retry', array_slice( $queue, -50 ), false );

    if ( ! wp_next_scheduled( 'wpide_mail_retry' ) ) {
        wp_schedule_single_event( time() + 10 * MINUTE_IN_SECONDS, 'wpide_mail_retry' );
    }
} );

add_action( 'wpide_mail_retry', function () use ( $wpide_retry_state ) {
    $queue = (array) get_option( 'wpide_mail_retry', array() );
    $left  = array();

    $wpide_retry_state->running = true;
    foreach ( $queue as $item ) {
        if ( ! wp_mail( $item['to'], $item['subject'], $item['message'], $item['headers'] ) && ++$item['attempts'] < 3 ) {
            $left[] = $item;
        }
    }
    $wpide_retry_state->running = false;

    update_option( 'wpide_mail_retry', $left, false );

    if ( $left ) {
        wp_schedule_single_event( time() + 10 * MINUTE_IN_SECONDS, 'wpide_mail_retry' );
    }
} );
```

## Notes

Emails with attachments are not retried because the attached files may be gone; the queue holds at most 50 emails.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Retry Emails That Failed to Send" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
