Troubleshooting Guide #

Common issues and solutions for the Message plugin.

🚨 Email Delivery Issues #

Emails Not Sending #

Symptoms:

  • Messages stuck in "Processing" status
  • No emails received by subscribers
  • Dashboard shows 0 sent

Diagnosis Steps:

  1. Check Cron Job

    # Verify cron is configured
    crontab -l | grep artisan
    
    # Test manually
    php artisan campaign:run
  2. Check SMTP Configuration

    # Test SMTP connection
    php artisan tinker
    >>> Mail::raw('Test', function($message) {
    >>>     $message->to('test@example.com')->subject('Test');
    >>> });
  3. Review Queue Status

    # Check for failed jobs
    php artisan queue:failed
    
    # Retry failed jobs
    php artisan queue:retry all

Solutions:

  • Cron not running: Add to crontab:

    * * * * * cd /path/to/project && php artisan schedule:run >> /dev/null 2>&1
  • SMTP misconfigured:

    • Verify credentials in Settings → Email Settings
    • Test connection with "Test Connection" button
    • Check firewall allows outbound SMTP
  • Queue workers stopped:

    php artisan queue:restart
    php artisan queue:work --daemon

Low Delivery Rate #

Symptoms:

  • High bounce rate (>5%)
  • Many emails marked as spam
  • Delivery rate below 95%

Solutions:

  1. Verify SPF/DKIM/DMARC

    v=spf1 include:sendgrid.net ~all
  2. Check Sender Reputation

    • Use tools like MXToolbox
    • Review blacklist status
    • Monitor complaint rates
  3. Improve Email Content

    • Avoid spam trigger words
    • Balance text-to-image ratio
    • Include unsubscribe link

Delayed Email Delivery #

Symptoms:

  • Emails arrive hours late
  • Queue backlog growing
  • Processing takes too long

Solutions:

  1. Optimize Batch Size

    // config/campaign.php
    'batch_size' => 50, // Reduce for faster processing
  2. Add Queue Workers

    # Run multiple workers
    php artisan queue:work --queue=campaigns --tries=3 &
    php artisan queue:work --queue=campaigns --tries=3 &
  3. Use Redis Queue

    QUEUE_CONNECTION=redis

📊 Dashboard & Analytics Issues #

Dashboard Not Loading #

Symptoms:

  • Blank dashboard
  • Spinning loader
  • Error messages

Solutions:

  1. Clear Cache

    php artisan cache:clear
    php artisan view:clear
    php artisan config:clear
  2. Check Permissions

    • Verify user has manage_messages permission
    • Confirm organization assignment
  3. Database Optimization

    OPTIMIZE TABLE campaign_messages;
    OPTIMIZE TABLE campaign_subscribers;

Incorrect Statistics #

Symptoms:

  • Open rates showing 0%
  • Click tracking not working
  • Wrong subscriber counts

Solutions:

  1. Rebuild Statistics

    // Via tinker
    $message = Message::find(1);
    $message->rebuildStats();
  2. Verify Tracking Pixel

    • Check email HTML includes tracking pixel
    • Confirm tracking domain is accessible
  3. Process Webhooks

    php artisan campaign:process-webhooks

Missing Performance Data #

Symptoms:

  • No data in last 30 days
  • Charts showing empty
  • KPIs displaying zero

Solutions:

  1. Check Date/Timezone

    // config/app.php
    'timezone' => 'America/New_York',
  2. Verify Data Collection

    • Ensure webhooks are configured
    • Check webhook delivery logs
    • Confirm tracking is enabled

🔌 SMTP & Server Issues #

SMTP Connection Failed #

Error Messages:

Connection could not be established with host smtp.example.com
Failed to authenticate on SMTP server

Solutions:

  1. Test with Telnet

    telnet smtp.sendgrid.net 587
  2. Common Fixes

    • Use correct port (587 for TLS, 465 for SSL)
    • Try authentication with base64 encoding
    • Check IP whitelisting requirements
  3. Firewall Issues

    # Check if port is open
    nc -zv smtp.sendgrid.net 587

SMTP Rate Limit Exceeded #

Symptoms:

  • 429 Too Many Requests errors
  • Temporary sending failures
  • Automatic failover triggered

Solutions:

  1. Implement Sending Windows

    'sending_window' => [
       'start' => '09:00',
       'end' => '17:00'
    ]
  2. Reduce Sending Rate

    'rate_limit' => 100, // per hour
    'batch_delay' => 10  // seconds
  3. Distribute Across Servers

    • Configure multiple SMTP servers
    • Enable load balancing mode

All SMTP Servers Failing #

Symptoms:

  • Test mode activated
  • No emails being sent
  • Multiple failover attempts

Emergency Steps:

  1. Quick Diagnostic

    # Test all servers
    php artisan campaign:test-smtp --all
  2. Common Causes

    • Account suspended
    • Credit/quota exhausted
    • IP blacklisted
    • Network outage
  3. Recovery Actions

    • Contact SMTP providers
    • Check account status
    • Review recent changes
    • Enable test mode temporarily

👥 Subscriber Issues #

Duplicate Subscribers #

Symptoms:

  • Same email appears multiple times
  • Import creates duplicates
  • Statistics inflated

Solutions:

  1. Clean Database

    -- Find duplicates
    SELECT email, COUNT(*) 
    FROM campaign_subscribers 
    GROUP BY email 
    HAVING COUNT(*) > 1;
    
    -- Remove duplicates (keep oldest)
    DELETE s1 FROM campaign_subscribers s1
    INNER JOIN campaign_subscribers s2 
    WHERE s1.id > s2.id 
    AND s1.email = s2.email;
  2. Add Unique Constraint

    Schema::table('campaign_subscribers', function($table) {
       $table->unique(['email', 'organization_id']);
    });

Subscribers Not Receiving Emails #

Symptoms:

  • Specific subscribers never get emails
  • No bounce or error messages
  • Status shows as sent

Diagnosis:

  1. Check Subscriber Status

    SELECT * FROM campaign_subscribers 
    WHERE email = 'user@example.com';
  2. Review Send Logs

    SELECT * FROM campaign_messages_subscribers 
    WHERE subscriber_id = 123;
  3. Common Issues

    • Subscriber unsubscribed
    • Email in suppression list
    • Invalid email format
    • Blocked by provider

Import Failures #

Symptoms:

  • CSV import shows errors
  • Subscribers not added
  • Timeout during import

Solutions:

  1. Check CSV Format

    • UTF-8 encoding required
    • Proper column headers
    • No special characters in headers
  2. Reduce Batch Size

    'import_batch_size' => 100, // Smaller batches
  3. Use Command Line

    php artisan campaign:import subscribers.csv --list=1

🔑 API Issues #

Authentication Failed #

Error:

{
  "error": "Invalid or expired token"
}

Solutions:

  1. Verify Token

    • Check token hasn't expired
    • Confirm token is active
    • Verify correct header format
  2. Check IP Restrictions

    • Review allowed IPs in API settings
    • Confirm request from whitelisted IP
  3. Test with Curl

    curl -H "Authorization: Bearer YOUR_TOKEN" \
        https://domain.com/api/campaign/subscribers

Rate Limit Exceeded #

Error:

{
  "error": "Too many requests",
  "retry_after": 3600
}

Solutions:

  1. Implement Exponential Backoff

    let delay = 1000;
    for (let i = 0; i < maxRetries; i++) {
     try {
       return await makeRequest();
     } catch (e) {
       await sleep(delay);
       delay *= 2;
     }
    }
  2. Request Rate Limit Increase

    • Contact support
    • Provide use case justification
  3. Optimize API Usage

    • Batch operations when possible
    • Cache responses
    • Use webhooks instead of polling

🔄 Webhook Issues #

Webhooks Not Triggering #

Symptoms:

  • No webhook deliveries logged
  • Events not being tracked
  • Missing email statistics

Solutions:

  1. Verify Webhook URL

    curl -X POST https://your-domain.com/webhook \
        -H "Content-Type: application/json" \
        -d '{"test": true}'
  2. Check Provider Configuration

    • SendGrid: Event Webhook settings
    • Mailgun: Webhook configuration
    • Ensure events selected
  3. Review Webhook Logs

    SELECT * FROM webhook_delivery_logs 
    ORDER BY created_at DESC 
    LIMIT 10;

Webhook Signature Validation Failed #

Error:

Webhook signature verification failed

Solutions:

  1. Verify Secret Key

    • Match provider's signing key
    • Check for trailing spaces
    • Ensure proper encoding
  2. Debug Signature

    $calculated = hash_hmac('sha256', $payload, $secret);
    $received = $_SERVER['HTTP_X_SIGNATURE'];
    Log::info('Signatures', compact('calculated', 'received'));

🎨 Template Issues #

Broken Email Layout #

Symptoms:

  • CSS not rendering
  • Images not showing
  • Mobile display issues

Solutions:

  1. Inline CSS

    'inline_css' => true, // config/campaign.php
  2. Use Absolute URLs

    <!-- Wrong -->
    <img src="/images/logo.png">
    
    <!-- Correct -->
    <img src="https://domain.com/images/logo.png">
  3. Test Email Clients

    • Use Litmus or Email on Acid
    • Check Gmail, Outlook, Apple Mail
    • Verify mobile rendering

💾 Database Issues #

Migration Errors #

Error:

SQLSTATE[42S01]: Base table or view already exists

Solutions:

  1. Reset Migrations

    php artisan plugin:refresh Albrightlabs.Campaign
  2. Manual Cleanup

    DROP TABLE IF EXISTS campaign_messages;
    DROP TABLE IF EXISTS campaign_subscribers;
    -- etc for all campaign tables
  3. Fresh Migration

    php artisan october:migrate --force

Database Connection Timeout #

Symptoms:

  • Slow page loads
  • Random timeouts
  • Connection pool exhausted

Solutions:

  1. Optimize Queries

    -- Add indexes
    ALTER TABLE campaign_subscribers 
    ADD INDEX idx_email (email);
    
    ALTER TABLE campaign_messages_subscribers 
    ADD INDEX idx_sent (sent_at);
  2. Increase Connection Pool

    // config/database.php
    'mysql' => [
       'max_connections' => 150,
    ]

📅 Message Schedule Issues #

Schedule Not Running #

Symptoms:

  • Next run time passed but message not sent
  • Schedule shows active but no sends occurring

Diagnosis:

  1. Check Cron Job

    crontab -l | grep artisan
    php artisan schedule:list
  2. Verify Schedule Status

    $schedule = MessageSchedule::find($id);
    echo "Active: " . ($schedule->is_active ? 'Yes' : 'No');
    echo "Next run: " . $schedule->next_run_at;
    echo "Runs: {$schedule->run_count}/{$schedule->max_runs}";
  3. Check Message Status

    SELECT * FROM campaign_messages WHERE id = X;
    -- Status should be 'scheduled' (code 7)

Solutions:

  • Ensure cron job runs every minute
  • Verify schedule is_active = true
  • Check max_runs not exceeded
  • Confirm message status is 'scheduled'

Wrong Send Time #

Symptoms:

  • Messages sent at incorrect hour
  • Time off by several hours

Solutions:

  • Verify schedule timezone matches desired timezone
  • Check server timezone: date
  • Account for Daylight Saving Time transitions
  • Test with php artisan campaign:run manually

👤 Sender Profile Issues #

Profile Not in Dropdown #

Symptoms:

  • Sender profile missing from selection
  • Empty dropdown on message form

Solutions:

// Check profile exists for organization
$profiles = SenderProfile::where('organization_id', $orgId)->get();

if ($profiles->isEmpty()) {
    // Create a profile first
}

Cannot Delete Profile #

Symptoms:

  • Error when trying to delete sender profile

Cause: Profile is used in messages

Solution:

// Check usage
$messageCount = $profile->messages()->count();

if ($messageCount > 0) {
    // Reassign messages to different profile first
    // Or mark profile as inactive instead of deleting
}

✉️ Email Validation Issues #

Disposable Email False Positives #

Symptoms:

  • Legitimate emails blocked as disposable

Solutions:

// Check disposable list
$checker = new DisposableEmailChecker();
$domains = $checker->getDisposableDomains();

// Whitelist specific domain
// Or disable disposable checking temporarily

Import Validation Failures #

Symptoms:

  • CSV import rejecting valid emails

Solutions:

  1. Check validation settings

    // Disable strict validation temporarily
    config(['campaign.validation.check_mx_records' => false]);
  2. Review failed emails

    tail -f storage/logs/campaign.log | grep validation
  3. Test individual email

    $validator = new EmailValidator();
    $result = $validator->validate('user@example.com');
    print_r($result);

🔍 Debug Mode #

Enable Detailed Logging #

// config/campaign.php
'debug' => true,
'log_level' => 'debug',

Check Log Files #

# Campaign specific logs
tail -f storage/logs/campaign.log

# Laravel logs
tail -f storage/logs/laravel.log

# Mail logs
tail -f storage/logs/mail.log

Use Debug Commands #

# Test configuration
php artisan campaign:test-config

# Test SMTP
php artisan campaign:test-smtp

# Debug subscriber
php artisan campaign:debug-subscriber user@example.com

# Process queue manually
php artisan campaign:process-queue --verbose

📞 Getting Support #

Before Contacting Support #

  1. Gather Information

    • Error messages
    • Log files
    • Steps to reproduce
    • System information
  2. Try Common Fixes

    • Clear cache
    • Restart services
    • Check documentation
  3. Prepare Details

    php artisan campaign:diagnostic > diagnostic.txt

Contact Methods #

  • Email: support@albrightlabs.com
  • Phone: (610) 756-5060
  • Documentation: Check relevant guides
  • Community: Forum and discussions

Information to Provide #

  • October CMS version
  • Campaign plugin version
  • PHP version
  • Error messages
  • Recent changes
  • Diagnostic output

Need more help? Contact support at support@albrightlabs.com