Troubleshooting and FAQ

The failures that actually happen, with the cause and the fix for each.

Start with /admin/diagnostics and storage/logs/. Between them they explain most of what follows.

Installation

Every address except the home page returns 404

The rewrite rules are not being applied. On Apache, mod_rewrite is disabled or AllowOverride is None, so .htaccess is ignored. On Nginx, the try_files line from installation is missing.

The installer says a folder is not writable

Set storage/ and everything under it to 0755, or 0775 where PHP runs as a different user than the file owner. The installer names the exact folder.

The installer cannot connect to the database

The message distinguishes the causes: no server answering at that host and port, access denied for that user, or the named database does not exist. On shared hosting the host is almost always localhost, and the database and user names carry your account prefix.

/install returns 404 on a fresh upload

An installed system has no installer. Either storage/installed.lock exists, or a .env with an application key is present and the database already holds an administrator. To install again deliberately, remove the lock file, empty the database, and delete .env.

The installer stopped part way through

Fix the cause and open /install again. An installation that never reached the administrator step reopens the wizard, and running it again is safe: the schema is applied idempotently and no second administrator is created.

Signing in

The sign-in form reloads with no message

SESSION_SECURE_COOKIE=true while the site is served over plain HTTP. The browser never returns the session cookie, so the form fails its security check silently. Set it to false until HTTPS works, then turn both it and FORCE_HTTPS on.

The password is correct but a code is demanded that nobody has

The account requires two-factor authentication and no authenticator has been paired. Sign in with the password: the next screen shows the QR code and pairs one. Save the recovery codes it then shows, because they are shown once.

An authenticator was lost

Use a recovery code in place of the six-digit code. If none are left, another Admin resets the second factor from the Users screen. If the only Admin is locked out, the recovery path is a support request, not a database edit.

Locked out after several attempts

Wait out LOGIN_LOCK_MINUTES. The limits are per account and per address; an office behind one address shares the second one, which is why LOGIN_IP_MAX_ATTEMPTS is set much higher.

Pages and addresses

A page says the host name is not recognised

The host in the request is not in ALLOWED_HOSTS. Add it, without the port, including the www. form if the site answers on it.

A blank white page

A PHP error with error display off, which is correct for a live site. Read storage/logs/php-error.log. The usual causes are a missing PHP extension and a memory_limit too low for rendering a PDF.

The application key page appears

APP_KEY is empty or missing from .env. The page offers a freshly generated value to paste. If the installation was working before, restore the original key from your backup instead: a new key makes stored SMTP passwords and two-factor secrets unreadable.

Email

Nothing is delivered

The scheduled email job is not running. See scheduled jobs, run it by hand once, and read the line it prints.

Mail is sent but arrives in spam

The sender address is on a domain without SPF, or on a domain you do not control. Use a mailbox on your own domain and publish SPF, and DKIM if your provider supports it.

Authentication failed against the mail server

Re-enter the password on the email settings screen. It is write-only: a blank field keeps the old value, so a mistyped password is not visible anywhere. Check the port and encryption pair as well, 587 with tls or 465 with ssl.

Certificates and imports

An import is rejected before any row is read

The header row does not match. Download the template from the import screen and compare it column by column; a trailing space or a renamed column is enough.

Every row is rejected for its dates

The spreadsheet reformatted them. Dates must be YYYY-MM-DD. Format both date columns as text before typing, and check the saved CSV in a text editor.

A certificate number is reported as already in use

Numbers and unique IDs are unique across the whole installation, including against certificates issued long ago and against revoked ones. Use your own numbering scheme rather than starting again at 1 each year.

A verified certificate is not found publicly

Check three things: the certificate is verified rather than assigned or rejected, it is not revoked, and the identifier being typed is the certificate number or the unique ID rather than the participant name. An unarchived revoked certificate shows only a revocation notice, without participant details, dates, a reason or a PDF. Pending, rejected, deleted and archived revoked records remain not found.

A PDF is slow the first time

It is rendered on first authorised access and stored. Later requests reuse the file while its appearance, verification and renderer are current. A template correction, renderer upgrade, later verification or six-month file cleanup triggers regeneration on the next authorised access. The approved business values stay fixed; appearance follows the current template and verification follows the current certificate. See stored PDFs and name corrections. Regeneration still needs the retained background assets.

Frequently asked

Can one installation serve several organisations?

No. One installation is one issuing organisation, with any number of verifier bodies. Run a separate installation, with its own database, for a second issuer.

Can participants log in?

No, and deliberately. Verification needs no account, so there is no participant password to lose and no participant data behind a login.

Can the interface be in another language?

English and Mongolian ship complete, and every visible string is editable from the translation screen without touching a file. A third language means adding a locale file, which is a developer task; see architecture overview.

Are national identity numbers stored?

No. There is no column for one anywhere, and adding one is explicitly out of scope. See security and privacy.

Can I edit a certificate after issuing it?

A misspelled name can be corrected, and the PDF is replaced in the same operation. The number, the identifiers, the issue and expiry dates, the course and the verification link are fixed once a document exists. Revoke and reissue if one of those business values is wrong. The approving organisation and verification date follow the current certificate, including a later verification. See stored PDF guidance.

CertiFlow 1.0.3 documentation. In your download, licence terms are in Licensing/ and sample import files are in Sample-Files/. Online documentation.

Certificate preview or site language

Public certificate previews use the browser's native PDF viewer when available, with the bundled canvas renderer as fallback. The embedded viewer requests a clean certificate view; use Open in a new tab for normal browser controls, or Download PDF. Viewer appearance can vary by browser. Keep the fallback renderer and worker from the same release together under public/assets/vendor/pdfjs/ and serve .mjs files as JavaScript. Keep application assets available on the same origin. No external PDF service receives the document. If loading fails, the page shows a translated error and the normal PDF download remains available.

If the site unexpectedly appears in English, see Choosing the language an installation runs in. Check browser negotiation and any stored account/session choice before replacing translation files.