POSMaster Help v1.2.0
Help & support

Troubleshooting

Find your problem in the list below. Each one shows what you see, why it happens and how to fix it.

Tip: Press Ctrl+K and type a word from the error message to jump straight to the right problem.

Many fixes use a terminal. If you have none, ask your host's support to run the command for you. The most useful command after changing .env is:

php artisan optimize:clear

Installation and server problems

Blank page or HTTP 500 error

What you see: A white page, or "500 | Server Error", right after you open the site or after an update.

Why: Something is wrong that the app hides from visitors. The usual causes are a wrong path in public/index.php, an unwritable storage folder, a missing .env file, a missing vendor folder, or the wrong PHP version.

How to fix:

  1. Open storage/logs/laravel.log and read the last lines. The real error is written there.
  2. Check that the .env file exists and that vendor/ is in the app folder.
  3. Make sure the site runs on PHP 8.2 or newer.
  4. Make storage and bootstrap/cache writable (see "Permissions on storage and bootstrap/cache" below).
  5. If the log is empty, set APP_DEBUG=true for a minute to see the error on screen, then set it back to false straight away.

Warning: Never leave APP_DEBUG=true on a live site. It can show passwords and paths to visitors.

"Vite manifest not found"

What you see: An error page that says Vite manifest not found at: .../public/build/manifest.json.

Why: The public/build folder is missing. It holds the CSS and JavaScript of the app. Some upload tools skip it, or it was not included in the source code you downloaded.

How to fix:

  1. Upload the public/build folder from the download package to your server. It must contain manifest.json and an assets folder.
  2. Or, if you have Node.js 18 or newer, run npm install && npm run build in the app folder.
  3. If you moved public into public_html, the folder must be public_html/build.

Images and logo do not show

What you see: Broken picture icons for the logo and product images. Everything else works.

Why: The browser reaches uploaded pictures through the link public/storage. The link is missing, or APP_URL does not match the address in your browser.

How to fix:

  1. Run php artisan storage:link. On hosting without a terminal, ask the host to create a symbolic link named storage in the public folder that points to storage/app/public.
  2. Open .env and check APP_URL. It must be exactly the address you type, including http:// or https:// and any sub-folder.
  3. Run php artisan optimize:clear.
  4. If the demo pictures are missing, upload the storage/app/public/demo folder from the package.

"No application encryption key has been specified"

What you see: An error page with that sentence when you open the site.

Why: APP_KEY in .env is empty. This is normal after an SQL import, because the installer did not run.

How to fix:

  1. Create a key with php -r "echo 'base64:'.base64_encode(random_bytes(32));" on any computer with PHP, or run php artisan key:generate on the server.
  2. Paste the whole result, starting with base64:, after APP_KEY= in .env.
  3. Run php artisan optimize:clear.

See Install by importing SQL for details.

419 Page expired

What you see: After you click Save or Sign in, the page says "419 | Page Expired".

Why: The security token of the form is no longer valid. Common reasons: the page stayed open longer than the session lifetime (120 minutes), the browser blocks cookies, APP_URL does not match the address you use, or the storage folder is not writable so sessions cannot be saved.

How to fix:

  1. Reload the page and try again.
  2. Check that APP_URL matches your address, and that you always open the site with the same address (with or without www, http or https).
  3. Make sure storage is writable and the sessions table exists in the database.
  4. If you moved to HTTPS, set SESSION_SECURE_COOKIE=true only after the whole site works on HTTPS, then clear the cache.

Permissions on storage and bootstrap/cache

What you see: "The stream or file could not be opened", "Permission denied", or a 500 error that mentions storage/logs or bootstrap/cache.

Why: The web server user cannot write to those two folders.

How to fix:

  • On cPanel File Manager, set storage and bootstrap/cache to 755, including sub-folders. Use 775 if 755 does not help.
  • On a VPS:
sudo chown -R www-data:www-data storage bootstrap/cache
sudo chmod -R ug+rwX storage bootstrap/cache

If a different user runs PHP on your server, use that user instead of www-data.

Slow first load

What you see: The first page after a long pause takes many seconds. Later pages are fast.

Why: On shared hosting the PHP process goes to sleep when nobody uses it. The first request must warm up the cache.

How to fix:

  1. Run php artisan optimize after every update. It stores the configuration, routes and views.
  2. Choose PHP 8.3 and turn on OPcache in your hosting panel.
  3. Use SESSION_DRIVER=database and CACHE_STORE=file (the defaults) unless you have Redis.
  4. For a busy shop, a small VPS is faster than shared hosting.

MySQL error 1071 or 1140 (strict mode and old versions)

What you see: An error such as SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long, or 1140 In aggregated query without GROUP BY.

Why:

  • 1071 happens with an old database (MySQL 5.6, MariaDB older than 10.2) when the tables are created, because it cannot index long utf8mb4 columns.
  • 1140 and similar errors appear when the database runs in strict mode (ONLY_FULL_GROUP_BY) and a query mixes totals with plain columns. POSMaster is built for strict mode, so this usually means a changed file or an unusual setup.

How to fix:

  1. Use MySQL 5.7 or newer, or MariaDB 10.4 or newer. See Requirements.
  2. Create the database with the collation utf8mb4_unicode_ci.
  3. Install by importing database/schema.sql instead of running migrations. See Install by importing SQL.
  4. For 1140, look at storage/logs/laravel.log to see which screen failed, and send that line to support. As a short-term workaround your host can remove ONLY_FULL_GROUP_BY from the database sql_mode.

Database connection refused or "Access denied"

What you see: "SQLSTATE[HY000] [1045] Access denied for user", "[2002] Connection refused", or "Unknown database".

Why: The DB_* values in .env are wrong, or the database user has no rights on the database.

How to fix:

  1. Check DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME and DB_PASSWORD. On cPanel the names start with your account prefix.
  2. Try DB_HOST=localhost or 127.0.0.1.
  3. In your hosting panel, add the user to the database with all privileges.
  4. If the password has special characters like # or a space, put it in quotes: DB_PASSWORD="my pass#word".
  5. Run php artisan optimize:clear.

Sign-in problems

Cannot sign in (inactive user, wrong branch, too many attempts)

What you see: "These credentials do not match our records", or "Too many login attempts. Try again in N seconds", or you sign in but cannot sell.

Why:

  • The email or password is wrong.
  • The user is inactive. Inactive users cannot sign in, and the message looks the same as a wrong password.
  • After 5 wrong tries for the same email and address, sign-in is blocked for a short time.
  • The user was not given a branch, or is working in a warehouse. Sales cannot be made from a warehouse.

How to fix:

  1. Check the email and password. Passwords are case sensitive.
  2. A manager or admin opens Users, edits the person and ticks Active — can sign in.
  3. In the same screen, select the user's Branches. Super Admin and Admin can use every branch.
  4. Wait for the countdown, or clear it with php artisan cache:clear.
  5. If you see "Sales cannot be made from a warehouse", switch to a store branch from the top bar.

Forgot the admin password

What you see: You cannot sign in as the only Super Admin, and "Change password" is not an option.

Why: There is no email reset, so the password must be changed from the server.

How to fix: Open a terminal in the app folder and run:

php artisan tinker

Then type these lines one by one (use your own email and a new password):

$u = App\Models\User::where('email', 'you@example.com')->first();
$u->password = 'A-New-Strong-Password';
$u->is_active = true;
$u->must_change_password = false;
$u->save();
exit

The password is saved safely hashed. Sign in, then change the password again in your profile. For a Docker install, run docker compose exec -u www-data app php artisan tinker.

Note: If you have no terminal, ask your host to run it, or restore a database from schema.sql into a new empty database and move your data over with an export.

Red banner about the default password

What you see: A red banner on every page: "You are using the default password from the installer. Change it now to keep your shop safe."

Why: You installed with schema.sql and still use admin@example.com with the password ChangeMe-123.

How to fix: Click Change password in the banner, enter the current password, choose a new one, and save. The banner goes away at once. See Install by importing SQL.

Demo mode

"This action is disabled in demo mode"

What you see: A red message when you delete something, change a password, edit a role or language, or change business settings.

Why: Demo mode is on. It blocks deleting and protects sensitive settings, so visitors cannot damage a demo shop.

How to fix:

  1. On the server, run php artisan pos:demo off (Docker: docker compose exec -u www-data app php artisan pos:demo off).
  2. If it says demo mode is locked, see the next problem.

Demo mode switch is missing, or demo mode cannot be turned off

What you see: The System & demo tab is missing from Settings, or php artisan pos:demo off says demo mode is locked.

Why: On purpose, the tab is hidden for everyone (even Super Admins) while demo mode is ON, so a demo account can never turn it off. If POS_DEMO_LOCK=true is set in .env (or .env.docker), even the server command refuses.

How to fix:

  1. If POS_DEMO_LOCK=true is set, change it to false in .env and run php artisan optimize:clear.
  2. Run php artisan pos:demo off.
  3. Reload the page. The tab is back.

Selling problems

"Not enough stock"

What you see: At checkout, "Not enough stock for PRODUCT. Available: 0".

Why: The branch you are selling from has less stock than you are trying to sell. Stock is kept per branch.

How to fix:

  1. Check the active branch in the top bar. The stock may be in another branch.
  2. Add stock with a purchase, a transfer or an adjustment (reason "opening" or "found").
  3. Or allow selling at zero: Settings → Sales & receipts and turn on Allow selling when stock is 0 (negative stock).

Negative stock appears in the reports

What you see: Some products show a negative quantity in Stock.

Why: Allow selling when stock is 0 (negative stock) is on, so sales were allowed beyond the quantity on hand.

How to fix: Add the missing stock with a purchase or an adjustment so the quantity is correct again. Turn the setting off in Settings → Sales & receipts if you want the POS to stop sales at zero.

Barcode scanner adds nothing

What you see: You scan an item and nothing happens, or the code appears in the wrong place.

Why: A USB or Bluetooth scanner works like a keyboard. It types the code and then presses Enter. It fails when the cursor is not in the POS search box, or when the scanner does not send Enter.

How to fix:

  1. Click in the search box, or press F2, before you scan.
  2. Set the scanner to add an Enter (CR) suffix. The manual of the scanner has a "suffix" barcode to scan.
  3. Check Settings → POS & scanner. In Barcode / QR scanning, if the mode is Device camera only, choose USB / Bluetooth scanner only or Scanner and camera.
  4. Scan the code into a plain text field (for example Notepad) to check that the scanner works.
  5. Check that the product has that exact barcode.

Camera scan button does nothing

What you see: You tap the camera icon on the POS and nothing opens, or the browser says the camera is blocked.

Why: Browsers only allow camera access on HTTPS (or localhost). Or camera permission was denied.

How to fix:

  1. Open the site with https://. See Install on web hosting for free certificates.
  2. Tap the lock icon in the address bar and allow Camera for the site.
  3. Close other apps that use the camera.
  4. Check Settings → POS & scanner. Barcode / QR scanning must be Device camera only or Scanner and camera.

Coupon not applied

What you see: The POS says the coupon is not valid or shows a message under the coupon box.

Why: The coupon has a rule that the sale does not meet. The message tells you which one.

How to fix: Open the coupon in Coupons and check:

  • Active is ticked and the code is typed exactly.
  • Today is between Starts on and Ends on ("This coupon is not active yet" or "has expired").
  • The sale reaches the Minimum order amount.
  • Total usage limit has not been reached.
  • If Uses per customer is set, select a customer on the sale first. That customer may also have used the coupon already.

Gift card cannot be used

What you see: "Gift card not found or not usable", or "Gift card balance is only ...".

Why: The card does not exist with that code, is not active, has expired, or has less balance than the amount you want to pay with it.

How to fix: Open the card in Gift cards and check the code, that Active is ticked, the Expires on date, and the Balance. If the balance is lower than the bill, take the rest with another payment method (split payment).

Printing and display

Receipt prints at the wrong size

What you see: The receipt is cut off, tiny, or printed on a big page.

Why: The paper size in POSMaster does not match the size in the browser's print window and the printer driver.

How to fix:

  1. Set Receipt paper in Settings → Sales & receipts to 58 mm, 80 mm or A4.
  2. In the print window choose your thermal printer, the same paper size, Margins: None and Scale: 100%.
  3. In the printer driver, create a custom paper size with the same width, such as 80 mm.

Thermal printer margins and blank paper at the end

What you see: Text is cut at the left or right, or the printer feeds a long blank strip.

Why: The driver adds default margins, or the page height is set too tall.

How to fix: In the print window turn off Headers and footers, set margins to None, and in the driver set the paper height to "roll" or "continuous". Turn on Print receipt automatically after each sale to avoid the dialog, and use a browser kiosk-printing option for silent printing if you need it.

Language upload rejected

What you see: "The file must be a JSON object like {"English text": "Translation"}", or the language code is refused.

Why: The file is not a valid JSON object (for example it is a list, has a missing comma, or has a stray comma at the end), or the code is not in the right format.

How to fix:

  1. Start from Languages → Download template. Edit only the text on the right of each colon.
  2. Keep the keys and placeholders such as :name exactly as they are.
  3. Validate the file with any JSON checker, and save it as UTF-8.
  4. Use a short ISO code like hi, pt or pt_BR (two or three lowercase letters, and optionally an underscore and two capital letters).

Arabic shows the wrong direction

What you see: Arabic text is left to right, or English text is mirrored.

Why: The Text direction of the language is wrong.

How to fix: Open Languages, edit the language, and set Text direction to Right to left (Arabic, Urdu, Hebrew) for Arabic, or Left to right for English and French. Save and reload the page.

Wrong dates or times (timezone)

What you see: Receipts and reports show the wrong time, or sales near midnight land on the wrong day.

Why: The timezone in the settings is wrong. The default is UTC.

How to fix: Open Settings → Business, choose your Timezone and Date format, and click Save settings. Old sales keep their saved time, and new sales use the new timezone.

Email problems

Emails are not sent or go to spam

What you see: After Send you get "Saved to the mail log (email sending is not set up, or demo mode is on).", or "The email could not be sent. Check Settings → Email.", or the customer never receives the email, or it lands in the spam folder.

Why:

  • Send email with in Settings → Email is still set to the log (the default), or demo mode is on. Then emails are only written to storage/logs/laravel.log.
  • The SMTP host, port, encryption, username or password is wrong. The error in brackets usually says which ("Connection refused", "Authentication failed", a timeout).
  • Email sent with the hosting server's own sendmail, or with a From address that does not belong to your domain, is often marked as spam.

How to fix:

  1. Open Settings → Email and choose SMTP.
  2. Copy the SMTP details from your email provider: host, port, encryption (TLS with 587, or SSL with 465), username and password. Many providers need an "app password" instead of your normal password.
  3. Use a From address of the same mailbox or domain as the SMTP account.
  4. Save, then click Send test email and check the inbox and the spam folder.
  5. If the host blocks outgoing ports 587 and 465, ask your host to open them, or use their own SMTP server.
  6. For reliable delivery use an SMTP service (your domain mailbox, Google Workspace, Microsoft 365, or a transactional service such as Brevo, Mailgun or Amazon SES), and ask it how to add the SPF and DKIM records for your domain.

If the SMTP password stopped working after moving the site or changing APP_KEY, type the password again and save. See PDF and email.

Offline mode and customer display

Offline mode is not ready

What you see: The POS shows "Offline mode is not ready: open the POS once while online.", or after a reload without a connection you see a page that says "Offline" instead of the POS.

Why:

  • The POS was never opened online in this browser by this cashier in this branch, or the cashier logged out (logging out clears the stored data).
  • The site runs on plain http://. Browsers only run the service worker that keeps the POS page available offline on HTTPS or localhost.
  • The browser data was cleared, or a private window is used.

How to fix:

  1. Put the site on HTTPS. See Install on web hosting for free certificates. On the shop computer itself, http://localhost also works.
  2. While online, sign in as the cashier, choose the branch and open the POS once. Wait for the products to load.
  3. Use a normal (not private) browser window and do not clear its data.
  4. On plain HTTP, keep the POS tab open: it keeps selling offline as long as you do not reload or close it.

See Offline mode.

Offline sales do not sync

What you see: The yellow bar still shows Waiting to sync after the connection is back, or the POS says "Sign in again to sync offline sales."

Why: The session ended while offline, a different cashier is signed in, or the server cannot be reached yet.

How to fix: Sign in again in the same browser as the cashier who made the sales, open the POS and click Sync now. Do not clear the browser data while sales are waiting: they are stored only in that browser. Differences found during the sync are listed under Sales → Offline sales review.

Customer display does not update

What you see: The customer display stays on the idle screen while you sell.

Why: The display only receives the cart from a POS in the same browser on the same computer.

How to fix: Close the display and open it again with the Display button in the POS. Do not use a different browser, a private window or a second device. See Customer display.

Scheduled jobs and Docker

Cron or nightly demo reset not running

What you see: The public demo is not reset at midnight, or scheduled jobs never run.

Why: The nightly reset needs three things together: POS_DEMO_RESET_NIGHTLY=true, demo mode on, and a cron job that runs every minute.

How to fix:

  1. Set POS_DEMO_RESET_NIGHTLY=true in .env and run php artisan optimize:clear.
  2. Make sure demo mode is on (php artisan pos:demo on, or Settings → System & demo → Turn demo mode ON), or set POS_DEMO_LOCK=true.
  3. Add the cron job from Install on web hosting.
  4. Test by hand with php artisan schedule:run. On Windows use Task Scheduler.
  5. With Docker, check that the scheduler container is running: docker compose ps.

Docker container: "Database not reachable"

What you see: In docker compose logs app the line "Database not reachable." and the app container stops.

Why: The app waited about two minutes and the database never accepted its login. The usual reason is a changed database password: the database volume keeps the password it was first created with.

How to fix:

  1. Run docker compose logs db to see what the database says.
  2. Make sure the POS_DB_* values in .env.docker are the same as the first time you started. Start with docker compose --env-file .env.docker up -d.
  3. If this is a new install with no data you need, reset the volumes with docker compose down -v and start again. This deletes all data.
  4. Run docker compose up -d again and install with docker compose exec -u www-data app php artisan pos:install --demo.

See Install with Docker.

Still stuck?

  1. Read the last lines of storage/logs/laravel.log (for Docker: docker compose logs -f app).
  2. Search this guide with Ctrl+K.
  3. Read the FAQ, including how to get support.
POSMaster 1.2.0 · Help for shop owners, managers and cashiers