Troubleshooting
1. "File not found" with Filesystem Sources
Error Message:
We could not find the file at '/path/to/file.csv' using the disk 'local'.
Causes:
- The path is relative (e.g.
imports/file.csvinstead of/absolute/path/file.csv). - The file does not exist on the configured disk.
- The disk is not configured correctly in
config/filesystems.php.
Solutions:
-
Use absolute paths:
->fromSource(SourceType::FILESYSTEM, ['path' => base_path('storage/app/imports/file.csv')]) -
Check existence:
use Illuminate\Support\Facades\Storage; Storage::disk('local')->exists('imports/file.csv'); // true/false -
Check disk configuration:
// config/filesystems.php 'disks' => [ 'local' => [ 'driver' => 'local', 'root' => storage_path('app'), ], ],
2. Memory Limit Errors
Error Message:
Allowed memory size of 134217728 bytes exhausted
Causes:
- The CSV/Excel file is too large for the current PHP
memory_limit. - Too many rows are processed at once (e.g.
chunkSizeis too large).
Solutions:
-
Increase
memory_limit(inphp.ini):memory_limit = 512M -
Use smaller chunks:
->setChunkSize(500) // Default: 100 -
Disable transactions (for maximum performance):
->transactionMode(TransactionMode::NONE) -
Optimize queue worker:
php artisan queue:work --memory=512
3. "Column not found" with strictHeaders(true)
Error Message:
The column 'user_email' was not found in the source file headers.
Causes:
- The CSV header does not match the definition in
map()orrelate(). - Case sensitivity or whitespace differences (e.g. "E-Mail" vs. "email").
Solutions:
-
Use aliases:
->map(['E-Mail', 'Email', 'user_email'], 'email') -
Set
strictHeaders(false)(if the column is optional):->strictHeaders(false) -
Adjust CSV file (e.g. with Excel or
sed):# Replace spaces in headers (Linux/Mac) sed -i '1s/ /_/g' input.csv
4. "Connection timeout" with Large Uploads
Error Message:
Connection timeout or Request timeout exceeded
Causes:
- The upload time exceeds PHP's
max_execution_time. - The web server has a lower timeout setting.
- The file is too large for the upload.
Solutions:
-
Adjust PHP configuration:
; php.ini max_execution_time = 300 upload_max_filesize = 100M post_max_size = 100M max_input_time = 300 -
Increase Web Server Timeout (nginx example):
client_max_body_size 100M; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 300; -
Implement chunked uploads in the frontend:
// For very large files const chunkSize = 1024 * 1024; // 1MB chunks // Implement chunk-by-chunk upload
5. "Queue worker is not running"
Error Message:
Job failed after maximum attempts
Causes:
- The queue worker is not running.
- The worker crashed or exceeded its time limit.
- Queue configuration is incorrect.
Solutions:
-
Start and monitor worker:
# Start php artisan queue:work # Monitor with Supervisord php artisan queue:work --daemon --sleep=1 --tries=3 -
Supervisor configuration (
/etc/supervisor/conf.d/laravel-worker.conf):[program:laravel-worker] process_name=%(program_name)s_%(process_num)02d command=php /path/to/your/project/artisan queue:work --sleep=3 --tries=3 --max-time=3600 autostart=true autorestart=true user=www-data numprocs=4 redirect_stderr=true stdout_logfile=/path/to/your/project/storage/logs/worker.log stopwaitsecs=3600 -
Check queue status:
php artisan queue:failed php artisan queue:retry all
6. "Foreign key constraint violation"
Error Message:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row
Causes:
relate()orrelateMany()cannot find the referenced record.- The referenced ID does not exist in the target table.
- The relationship is configured incorrectly.
Solutions:
-
Enable debug mode for relationships:
->relate('category_name', 'category', Category::class, 'name', createIfMissing: true) -
Validate data before import:
->beforeRow(function(array &$row) { // Check whether category exists if (!empty($row['category_name'])) { $exists = Category::where('name', $row['category_name'])->exists(); if (!$exists) { $row['category_name'] = 'Default Category'; // or throw exception } } }) -
Create missing records:
->relate('category_name', 'category', Category::class, 'name', createIfMissing: true)
7. "Invalid datetime format"
Error Message:
DateTime::__construct(): Failed to parse time string
Causes:
- The date format in the CSV does not match the expected format.
- Empty or invalid date values.
Solutions:
-
Implement date transformation:
->mapAndTransform('import_date', 'created_at', function($value, $row) { if (empty($value)) return null; // Try various formats $formats = ['d.m.Y', 'Y-m-d', 'm/d/Y', 'd/m/Y']; foreach ($formats as $format) { $date = DateTime::createFromFormat($format, $value); if ($date !== false) { return $date->format('Y-m-d H:i:s'); } } throw new \InvalidArgumentException("Invalid date format: {$value}"); }) -
Flexible validation:
->validate([ 'import_date' => 'nullable|date_format:d.m.Y|date_format:Y-m-d' ])
8. Performance is Very Slow
Symptoms:
- Importing 10,000 rows takes several minutes.
- High CPU and memory usage.
Causes:
- Inefficient database queries in hooks.
- Chunk size too small.
- Missing indexes in the database.
Solutions:
-
Optimize chunk size:
->setChunkSize(1000) // Increase for better performance -
Check database indexes:
-- Index for keyedBy column CREATE INDEX idx_products_email ON products(email); -- Foreign key indexes CREATE INDEX idx_products_category_id ON products(category_id); -
Optimize hooks:
// ❌ Bad: N+1 Queries ->afterRow(function($model, $row) { $model->category; // Loads category individually for each row }) // ✅ Good: Eager Loading ->afterRow(function($model, $row) { $model->load('category'); }) -
Optimize transactions:
->transactionMode(TransactionMode::CHUNK) ->setChunkSize(500) // Larger chunks with transactions
9. Debugging Techniques
Check Log Files
-
Laravel Logs:
tail -f storage/logs/laravel.log -
Queue Worker Logs:
tail -f storage/logs/worker.log -
Log database queries:
// In AppServiceProvider::boot() if (app()->environment('local')) { DB::listen(function($query) { Log::info($query->sql, $query->bindings); }); }
Test Import with Small Data Sets
-
Create test CSV:
name,email,price Test Product,test@example.com,19.99 Another Product,another@example.com,29.99 -
Perform a dry-run:
php artisan ingest:run product-importer --file=test.csv --dry-run
Step-by-Step Debugging
->beforeRow(function(array &$row) {
Log::debug('Processing row', ['row' => $row]);
})
->map('name', 'name')
->map('price', 'price')
->afterRow(function($model, $row) {
Log::debug('Row processed', ['model_id' => $model->id]);
})
10. Common Configuration Errors
Incorrect Source Type Configuration
// ❌ Wrong
->fromSource(SourceType::UPLOAD, ['path' => 'file.csv'])
// ✅ Correct
->fromSource(SourceType::FILESYSTEM, ['path' => 'file.csv'])
->fromSource(SourceType::UPLOAD) // No parameters for upload
Missing Permissions
// In your Policy
public function import(User $user)
{
return $user->hasPermissionTo('import-products');
}
Queue Configuration
// config/queue.php
'connections' => [
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90, // Important for long-running jobs
'after_commit' => false,
],
],
Next Steps When Problems Occur
- Check logs: Review Laravel and worker logs
- Validate configuration: Make sure all paths and permissions are correct
- Test with small data sets: Isolate the problem
- Check database performance: Indexes and query optimization
- Community support: Open an issue on GitHub with detailed information
For further help, visit the Documentation or create an issue in the GitHub Repository.