Missing Languages in Dropdown

Version

v5.12.27

Environment

Docker (Portainer)

Checklist

  • Can you replicate the issue on our v5 demo site https://demo.invoiceninja.com or Invoice Ninja?
    → No, demo shows full language list.
  • Have you searched existing issues?
    → Yes, nothing matches this case.
  • Have you inspected the logs in storage/logs/laravel.log for any errors?
    → Yes, unrelated Stripe error (see logs section).

Describe the bug

Only 3 languages show up in the dropdown (Afrikaans, Catalan, Indonesian).
Expected languages (like English, Dutch, etc.) are missing.
Also, invoices render in a different language (looks Swedish).

Steps To Reproduce

  1. Deploy Invoice Ninja v5.12.27 with Docker (Portainer).
  2. Log in as admin.
  3. Go to Settings → Localization → Language.
  4. Only 3 languages are available.

Expected Behavior

All default languages should be available (including English and Dutch).

Additional context

Checked inside the container: /var/www/app/resources/ exists but no lang/ folder is present.
It looks like the image might be missing the language files.

Screenshots

  • Language dropdown only shows 3 options.
  • Invoice showing in another language I don’t even know.


Logs

From /var/www/app/storage/logs/laravel.log (latest 50 lines):

#25 /var/www/app/vendor/laravel/framework/src/Illuminate/Console/Command.php(213): Illuminate\Container\Container->call()
#26 /var/www/app/vendor/symfony/console/Command/Command.php(318): Illuminate\Console\Command->execute()
#27 /var/www/app/vendor/laravel/framework/src/Illuminate/Console/Command.php(182): Symfony\Component\Console\Command\Command->run()
#28 /var/www/app/vendor/symfony/console/Application.php(1110): Illuminate\Console\Command->run()
#29 /var/www/app/vendor/symfony/console/Application.php(359): Symfony\Component\Console\Application->doRunCommand()
#30 /var/www/app/vendor/symfony/console/Application.php(194): Symfony\Component\Console\Application->doRun()
#31 /var/www/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\Component\Console\Application->run()
#32 /var/www/app/artisan(35): Illuminate\Foundation\Console\Kernel->handle()
#33 {main}
"}
[2025-09-14 19:28:55] production.ERROR: api_key cannot be the empty string {"exception":"[object] (Stripe\Exception\InvalidArgumentException(code: 0): api_key cannot be the empty string at /var/www/app/vendor/stripe/stripe-php/lib/BaseStripeClient.php:257)
[stacktrace]
#0 /var/www/app/vendor/stripe/stripe-php/lib/BaseStripeClient.php(70): Stripe\BaseStripeClient->validateConfig()
#1 /var/www/app/app/PaymentDrivers/StripePaymentDriver.php(125): Stripe\BaseStripeClient->__construct()
#2 /var/www/app/app/PaymentDrivers/Stripe/Jobs/StripeWebhook.php(69): App\PaymentDrivers\StripePaymentDriver->init()
#3 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): App\PaymentDrivers\Stripe\Jobs\StripeWebhook->handle()
#4 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/Util.php(43):
Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#5 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(95): Illuminate\Container\Util::unwrapIfClosure()
#6 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\Container\BoundMethod::callBoundMethod()
#7 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/Container.php(696): Illuminate\Container\BoundMethod::call()
#8 /var/www/app/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(126): Illuminate\Container\Container->call()
#9 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(170): Illuminate\Bus\Dispatcher->Illuminate\Bus\{closure}()
#10 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(127): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#11 /var/www/app/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(130): Illuminate\Pipeline\Pipeline->then()
#12 /var/www/app/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(126): Illuminate\Bus\Dispatcher->dispatchNow()
#13 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(170): Illuminate\Queue\CallQueuedHandler->Illuminate\Queue\{closure}()
#14 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(127): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#15 /var/www/app/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(121): Illuminate\Pipeline\Pipeline->then()
#16 /var/www/app/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(69): Illuminate\Queue\CallQueuedHandler->dispatchThroughMiddleware()
#17 /var/www/app/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(102): Illuminate\Queue\CallQueuedHandler->call()
#18 /var/www/app/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(442):
Illuminate\Queue\Jobs\Job->fire()
#19 /var/www/app/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(392):
Illuminate\Queue\Worker->process()
#20 /var/www/app/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(178):
Illuminate\Queue\Worker->runJob()
#21 /var/www/app/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(149): Illuminate\Queue\Worker->daemon()
#22 /var/www/app/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(132): Illuminate\Queue\Console\WorkCommand->runWorker()
#23 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\Queue\Console\WorkCommand->handle()
#24 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#25 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(95): Illuminate\Container\Util::unwrapIfClosure()
#26 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\Container\BoundMethod::callBoundMethod()
#27 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/Container.php(696): Illuminate\Container\BoundMethod::call()
#28 /var/www/app/vendor/laravel/framework/src/Illuminate/Console/Command.php(213): Illuminate\Container\Container->call()
#29 /var/www/app/vendor/symfony/console/Command/Command.php(318): Illuminate\Console\Command->execute()
#30 /var/www/app/vendor/laravel/framework/src/Illuminate/Console/Command.php(182): Symfony\Component\Console\Command\Command->run()
#31 /var/www/app/vendor/symfony/console/Application.php(1110): Illuminate\Console\Command->run()
#32 /var/www/app/vendor/symfony/console/Application.php(359): Symfony\Component\Console\Application->doRunCommand()
#33 /var/www/app/vendor/symfony/console/Application.php(194): Symfony\Component\Console\Application->doRun()
#34 /var/www/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\Component\Console\Application->run()
#35 /var/www/app/artisan(35): Illuminate\Foundation\Console\Kernel->handle()
#36 {main}
"}
dnlweijers@nuc:~$

...

Docker Compose (redacted)

version: '3.8'

services:
  invoiceninja:
    image: invoiceninja/invoiceninja:5
    container_name: invoice-ninja-app
    restart: unless-stopped
    environment:
      APP_URL: https://invoice.dnlweijers.nl
      APP_ENV: production
      APP_KEY: base64:****   # redacted
      APP_DEBUG: true
      APP_DEFAULT_LOCALE: nl
      TRUSTED_PROXIES: '*'
      PDF_GENERATOR: snappdf
      SESSION_DRIVER: file
      QUEUE_CONNECTION: database
      IS_DOCKER: true
      DB_HOST: mariadb
      DB_PORT: 3306
      DB_DATABASE: invoiceninja
      DB_USERNAME: invoiceninja
      DB_PASSWORD: ****       # redacted
      MAIL_MAILER: smtp
      MAIL_HOST: mail.zxcs.nl
      MAIL_PORT: 465
      MAIL_USERNAME: ****     # redacted
      MAIL_PASSWORD: ****     # redacted
      MAIL_ENCRYPTION: ssl
      MAIL_FROM_ADDRESS: **** # redacted
      MAIL_FROM_NAME: "Factuur | DNLWEIJERS"
      ERROR_EMAIL: ****       # redacted
      NINJA_ENVIRONMENT: "selfhost"
    volumes:
      - /data/invoice-ninja/public:/var/www/app/public
      - /data/invoice-ninja/storage:/var/www/app/storage
    networks:
      - apps_network
      - invoice-ninja_intern
    depends_on:
      mariadb:
        condition: service_healthy
      redis:
        condition: service_healthy

  nginx:
    image: nginx:stable
    container_name: invoice-ninja-nginx
    restart: unless-stopped
    ports:
      - "8543:80"
    volumes:
      - /data/invoice-ninja/nginx:/etc/nginx/conf.d:ro
      - /data/invoice-ninja/public:/var/www/app/public:ro
      - /data/invoice-ninja/storage:/var/www/app/storage:ro
    networks:
      - apps_network
      - invoice-ninja_intern
    depends_on:
      - invoiceninja

  mariadb:
    image: mariadb:10.6
    container_name: invoice-ninja-mariadb
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ****  # redacted
      MYSQL_DATABASE: invoiceninja
      MYSQL_USER: invoiceninja
      MYSQL_PASSWORD: ****       # redacted
    volumes:
      - /data/invoice-ninja/mariadb:/var/lib/mysql
    networks:
      - invoice-ninja_intern
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p****"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:alpine
    container_name: invoice-ninja-redis
    restart: unless-stopped
    volumes:
      - /data/invoice-ninja/redis:/data
    networks:
      - invoice-ninja_intern
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

networks:
  apps_network:
    external: true
  invoice-ninja_intern:

Hi,

It may help to clear the app cache, here are more details from ChatGPT

Thanks for the clear repro — this sounds like the “seeded data didn’t load / cache stuck” combo that sometimes happens on fresh/self-hosted installs.

Here’s a quick, surgical checklist that usually restores the full language list and fixes “PDF shows in the wrong language”:

Fix the missing languages

  1. Run the post-update task inside the app container (this re-runs migrations, refreshes the built-in seed data like languages/currencies, and warms caches):
docker exec -it <your_app_container_name> php artisan ninja:post-update

This is the recommended maintenance step after updates/deploys and is safe to run again. (invoiceninja.github.io)

  1. Clear the app caches (either way):
docker exec -it <app> php artisan optimize:clear

…and then load any app page once with ?clear_cache=true appended (forces a UI-level cache bust).

  1. Confirm the languages exist in DB (optional but handy):
docker exec -it <db_container> mysql -u <user> -p<pass> <database> -e "SELECT COUNT(*) AS languages FROM languages;"

You should see a healthy count (dozens). If it’s still “3”, the seeding didn’t run — re-run step 1, and check your app logs (storage/logs/laravel.log) for migration/permission errors.

Stop invoices rendering in the “wrong” language

Invoice Ninja applies language at a few levels; if any of these differ, PDFs/portal can appear in a different language:

  • Company language: Settings → Localization → Language
  • User language (for the admin you’re logged in as): Settings → User Details → Language
  • Per-client language: Client → Edit → Settings → Language

If your client has (for example) Swedish set, their portal/PDF will render Swedish even if the company is English. Make sure these are aligned the way you expect. (invoiceninja.github.io)

If it still shows only 3 languages

  • Make sure you’re on v5.12.27 in the app footer/build info and that the container could write storage/ and bootstrap/cache/ (read-only volumes can block seeding/cache writes).

  • Check logs for migration/DB connection issues (storage/logs/laravel.log).

  • Re-run:

    docker exec -it <app> php artisan ninja:post-update
    docker exec -it <app> php artisan optimize:clear
    
  • Then hard-refresh the browser (or try a private window) to rule out a front-end cache.

1 Like

It solved it! Thank you so much!!! I tried it using ChatGPT and it just didn’t work. Have a nice day!

Glad to hear it, thanks for the update!