Skip to main content
Use the categories below to find the issue closest to what you are experiencing. Each accordion describes the symptom, the likely cause, and concrete steps to fix it.

Installation issues

Symptom: You see a Permission denied or failed to open stream error immediately after uploading files, or the app returns a blank 500 page on first load.Cause: The storage/ and bootstrap/cache/ directories are not writable by the web server process.Solution:
chmod -R 775 storage/ bootstrap/cache/
chown -R www-data:www-data storage/ bootstrap/cache/
If your server runs PHP under a different user (e.g. nginx or apache), replace www-data with the correct user. Confirm which user PHP-FPM runs as:
ps aux | grep php-fpm
Symptom: Running composer install --optimize-autoloader --no-dev prints Allowed memory size of X bytes exhausted.Cause: PHP’s default memory limit (often 128 MB) is too low for Composer to resolve the dependency graph.Solution:
COMPOSER_MEMORY_LIMIT=-1 composer install --optimize-autoloader --no-dev
Alternatively, pass the limit directly:
php -d memory_limit=2G /usr/local/bin/composer install --optimize-autoloader --no-dev
Symptom: Laravel prints No application encryption key has been specified or sessions fail immediately.Cause: The .env file is missing APP_KEY, or the value was not copied from the provided .env.Solution:Only run this if APP_KEY is blank. Running it on an existing live site will invalidate all encrypted data and active sessions.
php artisan key:generate
Then verify the value is present in .env:
grep APP_KEY .env
Symptom: Visiting the site shows a directory listing, or index.php is downloaded instead of executed. The .env file may be publicly accessible.Cause: The web server document root points to the project root instead of the public/ sub-directory.Solution: Update your virtual host or hosting panel to set the document root to public/. For Apache:
DocumentRoot /var/www/tripfy.africa/public
For Nginx:
root /var/www/tripfy.africa/public;

Database issues

Symptom: php artisan migrate throws an error such as SQLSTATE[42S01]: Base table or view already exists or hangs indefinitely.Cause: A previous partial migration left the schema in an inconsistent state, or the database user lacks CREATE TABLE / ALTER TABLE privileges.Solution:Check current migration state:
php artisan migrate:status
Rollback the last batch and retry:
php artisan migrate:rollback
php artisan migrate
Force-run in production (bypasses confirmation prompt):
php artisan migrate --force
Run a specific migration file only:
php artisan migrate --path=database/migrations/2026_01_01_000001_tripfy_africa_fixes.php
Symptom: Laravel logs show SQLSTATE[HY000] [1045] Access denied for user.Cause: The DB_USERNAME or DB_PASSWORD in .env does not match what is configured in MySQL, or the user does not have permissions on the target database.Solution:Verify credentials manually:
mysql -u your_db_user -p your_database_name
Grant the required permissions if needed:
GRANT ALL PRIVILEGES ON your_database_name.* TO 'your_db_user'@'localhost';
FLUSH PRIVILEGES;
After updating .env, clear the config cache:
php artisan config:clear && php artisan config:cache
Symptom: SQLSTATE[HY000] [2002] Connection refused or the page hangs before returning a database error.Cause: MySQL is not running, or DB_HOST / DB_PORT in .env point to the wrong address.Solution:Check the MySQL service:
sudo systemctl status mysql
Restart it if it is down:
sudo systemctl restart mysql
For shared hosting where the host is not 127.0.0.1, ask your provider for the correct internal hostname and update DB_HOST accordingly.

Queue and Redis issues

Symptom: Emails, notifications, or background tasks are never delivered. php artisan queue:failed shows a growing list of failed jobs.Cause: No queue worker is running. With QUEUE_CONNECTION=database (the default in .env.example), jobs accumulate in the jobs table but are not processed unless a worker is active.Solution:Run the worker manually to test:
php artisan queue:work --tries=3 --timeout=60
For production, keep the worker alive with Supervisor. Create /etc/supervisor/conf.d/tripfy-worker.conf:
[program:tripfy-worker]
command=php /path/to/tripfy.africa/artisan queue:work --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/var/log/supervisor/tripfy-worker.log
Then reload Supervisor:
sudo supervisorctl reread && sudo supervisorctl update
sudo supervisorctl start tripfy-worker:*
Retry all failed jobs:
php artisan queue:retry all
Symptom: When QUEUE_CONNECTION=redis or CACHE_DRIVER=redis is set, you see Connection refused errors or Predis\Connection\ConnectionException.Cause: Redis is not running, or REDIS_HOST / REDIS_PORT in .env are incorrect.Solution:Check the Redis service:
sudo systemctl status redis
Test the connection from the command line:
redis-cli ping
# Expected output: PONG
Verify the connection from within Laravel:
php artisan tinker
>>> Redis::ping();
If Redis is not available and you do not need it, switch the relevant drivers in .env back to file or database:
CACHE_DRIVER=file
QUEUE_CONNECTION=database
SESSION_DRIVER=file

Payment issues

Symptom: A payment succeeds on the gateway side but the booking status in Tripfy Africa stays pending. No entry appears in transactions.Cause: The gateway cannot reach your webhook URL, or the route is blocked by a firewall / CSRF middleware.Solution:Confirm the webhook URL is reachable:
curl -X POST https://tripfy.africa/api/payment/stripe/test
Check the application log for incoming webhook entries:
tail -f storage/logs/laravel.log
Verify that the webhook endpoint is listed in routes/web.php and is excluded from CSRF protection in app/Http/Middleware/VerifyCsrfToken.php:
protected $except = [
    'api/payment/*',
];
Ensure the correct webhook URL is registered in the gateway dashboard (Stripe, Razorpay, etc.) and that your server is publicly accessible on port 443.
Symptom: After saving API keys in Admin → Payment Gateways, payments still fail with an authentication error from the gateway.Cause: The parameters JSON in the gateways table was not saved correctly, or the environment is set to test when you need live (or vice versa).Solution:
  1. In the admin panel, go to Payment Gateways and click Edit on the gateway.
  2. Re-enter your API keys and confirm the Environment toggle matches your keys (test keys only work in test mode).
  3. Click Save, then re-test a payment.
If the issue persists, inspect the gateways row directly:
SELECT code, environment, is_sandbox, parameters FROM gateways WHERE code = 'stripe';

Email issues

Symptom: Emails are not sent and the log contains Swift_TransportException: Connection could not be established with host.Cause: The SMTP credentials in .env are wrong, or the port is blocked by a firewall.Solution:Test the SMTP port is reachable:
telnet smtp.gmail.com 587
Verify your .env mail settings:
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_ENCRYPTION=tls
MAIL_USERNAME=[email protected]
MAIL_PASSWORD=your_app_password
MAIL_FROM_ADDRESS=[email protected]
MAIL_FROM_NAME="Tripfy Africa"
Send a test email from Tinker:
php artisan tinker
>>> Mail::raw('Test', function ($m) { $m->to('[email protected]')->subject('Test'); });
Symptom: No SMTP error appears, but recipients never receive emails. php artisan queue:failed shows failed mail jobs.Cause: The queue worker is not running (see Jobs queued but never processed), or MAIL_MAILER is set to log instead of smtp.Solution:Check the mailer driver:
grep MAIL_MAILER .env
Process failed jobs:
php artisan queue:failed
php artisan queue:retry all
Clear and rebuild the config cache after any .env change:
php artisan config:clear && php artisan config:cache
Symptom: Emails arrive with literal placeholder text such as [[package_title]] or [[guide_name]] instead of real values.Cause: The template is referencing variables that were not passed to the notification, or a custom template was added without the correct short_keys mapping.Solution:Check the short_keys JSON for the relevant template in Admin → Notification Templates. It should list every [[variable]] the template uses.For NEW_BOOKING_RECEIVED, the expected keys are:
{
  "guide_name": "Tour Guide Name",
  "package_title": "Package Title",
  "trx_id": "Booking Transaction ID",
  "traveler_name": "Traveler Full Name",
  "traveler_email": "Traveler Email",
  "traveler_phone": "Traveler Phone",
  "tour_date": "Tour Date",
  "total_persons": "Total Persons",
  "total_price": "Total Price",
  "message": "Traveler Special Request"
}

File upload issues

Symptom: Images or documents appear to upload successfully, but the file is not shown afterwards and no path is stored in the database.Cause: The storage/app/public directory is not linked to public/storage, so files are saved but not publicly accessible.Solution:Create the symbolic link:
php artisan storage:link
Verify the link exists:
ls -la public/storage
Also confirm storage/app/public is writable:
chmod -R 775 storage/app/public
Symptom: File uploads fail with InvalidAccessKeyId or NoSuchBucket when FILESYSTEM_DISK is set to s3 or spaces.Cause: The cloud storage credentials in .env are incorrect or the bucket does not exist in the specified region.Solution:For AWS S3, verify these .env values:
FILESYSTEM_DISK=s3
AWS_ACCESS_KEY_ID=your_key
AWS_SECRET_ACCESS_KEY=your_secret
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=your_bucket_name
For DigitalOcean Spaces:
FILESYSTEM_DISK=spaces
DIGITALOCEAN_SPACES_KEY=your_key
DIGITALOCEAN_SPACES_SECRET=your_secret
DIGITALOCEAN_SPACES_ENDPOINT=https://sfo2.digitaloceanspaces.com
DIGITALOCEAN_SPACES_REGION=sfo2
DIGITALOCEAN_SPACES_BUCKET=your_bucket
After updating .env, clear the config cache:
php artisan config:clear && php artisan config:cache

Production issues

Symptom: The browser shows a generic 500 error or a blank white page.Cause: A PHP exception is being thrown but APP_DEBUG=false hides the details from the browser.Solution:Read the Laravel log to find the actual exception:
tail -f storage/logs/laravel.log
Temporarily enable debug mode on a staging copy (never on live) to see the full stack trace in the browser:
# .env (staging only)
APP_DEBUG=true
Common causes and quick fixes:
CauseFix
Missing .envCopy and configure .env from .env.example
APP_KEY emptyRun php artisan key:generate
storage/ not writableRun chmod -R 775 storage/ bootstrap/cache/
Config cache staleRun php artisan config:clear && php artisan config:cache
Missing Composer packagesRun composer install --optimize-autoloader --no-dev
Symptom: You updated a value in .env but the application behaviour has not changed.Cause: Laravel reads from its compiled config cache (bootstrap/cache/config.php) rather than .env directly when config:cache has been run.Solution:
php artisan config:clear
php artisan config:cache
To clear all caches at once:
php artisan optimize:clear
Then rebuild the production cache:
php artisan optimize
php artisan config:cache
php artisan route:cache
php artisan view:cache
Symptom: Logged-in users are randomly redirected to the login page, or a user’s session does not persist across requests.Cause: The session driver is misconfigured, the session lifetime is too short, or the storage/framework/sessions directory is not writable.Solution:Check SESSION_DRIVER in .env. For file-based sessions (the default), ensure the sessions directory is writable:
chmod -R 775 storage/framework/sessions
For Redis-based sessions, verify Redis is running and the connection details are correct (see Redis connection refused).Adjust the session lifetime in .env if it is too short:
SESSION_LIFETIME=120
After changing session configuration, clear the config cache:
php artisan config:clear && php artisan config:cache
Symptom: The frontend loads but uses default or incorrect colours instead of the brand colours set in Admin → Basic Control.Cause: The dynamic CSS file has not been generated yet, or it was overwritten during a file upload.Solution:Regenerate the CSS from the command line:
php artisan tinker
>>> app(\App\Http\Controllers\Admin\BasicControlController::class)->generateDynamicCssPublic();
Alternatively, log in to the admin panel, navigate to Settings → Basic Control, and click Save — this regenerates public/assets/themes/adventra/css/tripfy.css automatically.

Build docs developers (and LLMs) love