MSP AlignMSP Align Suggest a feature Docs GitHub

Troubleshooting

The messages below are the ones MSP Align shows, so you can search this page for the words on your screen. Commands are for a dedicated server; in Docker, run align commands as docker compose exec app align … and read the log with docker compose logs app.

Useful everywhere: sudo align check (health check), the app's error log /var/log/apache2/msp-align-error.log, and Administration → Audit log (your name, top right).

Installing

You see What to do
This installer targets Debian 13 Use a Debian 13 VM. ALIGN_FORCE=1 tries anyway, unsupported.
Run as root Run it with sudo -E bash as shown, or as root. A minimal Debian may need apt install -y curl sudo first.
git clone failed. Check the token has Contents: Read… Only for a private fork: the token in GH_TOKEN needs Contents: Read-only on that repository, and ALIGN_REPO=owner/name must match it.
No release signed with the MSP Align release key was found The download couldn't find a signed release. Check the server can reach github.com. A fork needs its own key in deploy/release-signers, or none (see Signed releases).
certbot failed - the site is on plain HTTP Let's Encrypt needs public DNS pointing at the server and port 80 open from the internet. Fix that, then run the certbot --apache -d … command it prints.
Proxy IP '…' is not valid Proxy mode takes one IP address, not a range or a list.
Install stopped at line … The command it names failed; the lines above it say why. Fix it and run the installer again: it's safe to repeat.

Signing in

You see What to do
Too many failed attempts. Wait 15 minutes and try again. Five wrong passwords lock the account for 15 minutes (ten from one address, across accounts). Wait it out.
The page doesn't load at all after many failures fail2ban banned the address for an hour (dedicated installs, not proxy mode): sudo fail2ban-client set msp-align unbanip <IP>.
That code is not valid. Check the time on the phone and on the server (timedatectl; the installer turns on time sync). Each code works once.
Lost phone or authenticator Another admin can use Remove 2FA on the user list (Administration → Staff & portal users), or on the server: sudo align user:reset-password --email=you@example.com --clear-2fa. It prints a one-time password; you set up a new authenticator at the next sign-in.
A password stopped working, with a Password replaced after wrong two-factor codes alert After 50 wrong codes in a row following the correct password, Align replaces the password and ends that person's sessions (2.2.1): someone else probably knows it. An admin sets a new one (Reset password, or sudo align user:reset-password); a portal user uses Forgot password.
Calendar feed stopped updating A password change, 2FA change or "sign out everywhere" turns off the feed link (2.2.1). Make a new one on the Meetings page and subscribe again.
No admin can sign in sudo align user:create --email=you@example.com --role=admin
A client can't sign in to the portal On the client's Client portal page, use Reset 2FA (they get a link to choose a new password and set up two-factor), or invite them again.

A restore signs everyone out, and a password change or 2FA reset signs that person out everywhere; that's on purpose.

Integrations

Each integration has Test connection (email: Send test). The message after test failed: says what the other system answered.

You see What to do
Connection failed: … The server can't reach the address: DNS, firewall, or a typo in the URL. Try curl -I <address> on the server.
Align won't connect to …: it is this server (loopback) (or a link-local or cloud metadata address) Since 2.2.1 integrations never reach the server itself or cloud metadata addresses. For an integration installed on the same machine, set 'allow_local_integrations' => true in /etc/msp-align/config.php. Addresses on your network (10.x, 172.16-31.x, 192.168.x) work as before.
HTTP 301/302 … (a redirect: check the address) Redirects aren't followed (2.2.1). Enter the final address, usually with https:// and without a trailing page.
SSL certificate problem / unable to get local issuer certificate Addresses must be https:// with a certificate this server trusts. For an internal certificate authority, copy its certificate to /usr/local/share/ca-certificates/ as a .crt file and run sudo update-ca-certificates.
HTTP 401 or HTTP 403 from … The key or credentials are wrong, expired or missing a permission. The integration's page lists what it needs.
…returned a non-JSON response. Check the ITFlow URL. Use ITFlow's base address (https://itflow.example.com), not a page inside it.
(no clients returned - check the key user's client access) The ITFlow API key works but its user can't see any clients.
NinjaOne did not return an access token. Check the client ID and secret, the grant type (Client credentials), the Monitoring scope and the Instance (US, US2, CA, EU or OC).
Tactical RMM sent something other than a list… or has no /clients/ at that address Enter Tactical's API address, the one its agents report to (often https://api.your-domain), not the dashboard's (https://rmm.your-domain).
KnowBe4 refused the token Make a new Reporting API token in that client's KnowBe4 console (Account Settings → Account Integrations → API, with Enable Reporting API Access on) and check the region: the start of the console's address (training.knowbe4.com is US, eu.knowbe4.com is EU…).
KnowBe4 refused … (HTTP 403) The Reporting API needs a Platinum, Diamond or SAT Foundations/Advanced subscription.
KnowBe4's request limit for this account was reached KnowBe4 limits requests per console (and locks a token out for 5 minutes after a burst). The last results stay; the next sync reads again.
No KnowBe4 form on a client's training card Switch KnowBe4 on under Integrations → KnowBe4. The form is for admins only.
Datto RMM refused the API key or secret key Check both keys (Setup → Users → the API user; generating new keys replaces the old ones), that Enable API Access is on under Setup → Global Settings → Access Control, and that the user isn't disabled.
Datto RMM has no sign-in at… or sent something other than a list Pick the platform named in the user's API URL (for example merlot in https://merlot-api.centrastage.net).
Datto RMM refused … (HTTP 403) or asked Align to slow down The API user's security level must allow viewing sites and devices. Datto also limits requests for the whole account (shared with your other tools) and pauses a caller that keeps going: Align stops for the run and carries on at the next sync.
Datto RMM devices have no make, model or serial yet Datto gives hardware one device at a time; Align reads up to 200 per hourly sync, so a large account fills in over a few hours (a device's type can change once it arrives, for example to virtual). The sync history shows how many are still to read.
HaloPSA refused the client ID or secret or has no token address Check the client ID and secret (a new secret is made when the authentication method changes), that the application is Active and uses Client ID and Secret (Services). Leave the authorisation server and tenant empty unless Halo's API page (Configuration → Integrations → HaloPSA API) shows ones that differ from your Halo address.
HaloPSA won't let the API application read… or refused the read permissions On the application's Permissions tab allow read:customers, read:assets and read:invoices, and make sure the agent it logs in as can see every client: clients it can't see are archived in Align.
HaloPSA has no /api/… at that address or sent something other than a list Enter your Halo web address (https://yourco.halopsa.com), without /api.
HaloPSA shows Not in use Another PSA (ITFlow) is this install's PSA. An install has one PSA because it decides the client list; nothing is read from the other.
Tactical RMM refused the API key Check the key under Settings → Global Settings → API Keys, and that its user's role has List clients and List agents. The role must cover every client: agents the key can't see are marked removed in Align.
this does not look like the VSPC REST API v3 Enter the Veeam Service Provider Console's own address; the API is /api/v3 on the same host.
Microsoft 365: AADSTS7000215 Paste the secret's Value, not its Secret ID.
Microsoft 365: AADSTS7000222 The client secret has expired: make a new one in Entra.
Microsoft 365: AADSTS65001 Grant admin consent for the app's permissions in Entra.
Microsoft 365: AADSTS50011 The redirect URI in Entra must be https://<your server>/settings/email/callback.
Google: unauthorized_client Domain-wide delegation for the service account is missing or has the wrong scopes in the Google Admin console.
SMTP: doesn't offer STARTTLS Choose TLS from the start (usually port 465), or the port your provider documents.
SMTP: refused the user name or password Check the account; many providers need an app password.

Sync and email

Problem What to do
Data isn't updating Integrations → Sync history shows each run and its errors. Run one now: Run sync now, or sudo align sync. Timers: systemctl list-timers 'msp-align*'; logs: journalctl -u msp-align-sync (and -psa, -mail).
A sync is already running. Wait for it to finish; Sync history shows it.
Emails aren't arriving Settings → Notifications → Email log shows each message and why it failed; failed messages are tried six times over about five hours. sudo align mail:test --to=you@example.com sends one now.
Email is not set up Set up Integrations → Email (Microsoft 365, Google Workspace or SMTP).
Portal invites point at the wrong address Links use base_url in /etc/msp-align/config.php (Docker: ALIGN_URL). Set it to the address clients use.

Updates

You see What to do
Could not reach GitHub to check for updates The server needs HTTPS access to github.com (and, for a private fork, a valid token in /etc/msp-align/github-token).
There is no newer release signed with the MSP Align release key The code on this server isn't a signed release, and there's no signed release to move to yet (for example right after upgrading from 1.x, before the release is published). Check the server can reach github.com and try again later; a fork needs its own key in deploy/release-signers.
Not signed with the release key, so not installed A release tag on GitHub isn't signed with the project's key, so it was refused and a security alert was sent. Don't install it by hand; check mspalign.org for news first.
The installer reported an error… A safety copy of the data was kept The update log on the page shows the failing step. If the update had no database changes, the previous version was put back. Download the safety copy before trying again.
The update and backup service is not installed on this server yet Run sudo msp-align-update once on the server.
Everyone sees being updated or being restored for a long time It clears when the job ends. If the server restarted mid-job, sudo systemctl start msp-align-update-check clears a stale one (the page also stops showing it after three hours). Logs: journalctl -u msp-align-agent.
Docker: the Updates page shows a command instead of a button That's expected: docker compose pull && docker compose up -d.

Backups and restores

You see What to do
Paste the backup key: it starts with AGE-SECRET-KEY-1 or That is not a backup key Paste the private key: it starts with AGE-SECRET-KEY-1 and is 74 characters long.
This key can't open the backup Each server has its own backup key: use the key of the server that made the backup.
This backup is from version …, newer than this server (or …was made by version …) Update this server first, then restore.
That file is larger than this server accepts Restore from the command line: copy the file to the server and run sudo msp-align-restore FILE. Behind a proxy, also raise the proxy's upload limit.
Docker: …this container takes its key from ALIGN_APP_KEY Remove ALIGN_APP_KEY from .env (the backup carries its own key), restart, and restore again.
Lost the backup private key Backups made with it can't be opened by anyone. Make a new key pair: sudo mv /etc/msp-align/backup-recipient.txt /root/old-backup-recipient.txt && sudo msp-align-update, store the new private key from /root/msp-align-backup-key.txt in your password manager (then sudo shred -u that file), and download a new backup right away.

A restore that fails puts the previous data back on its own.

Behind a reverse proxy

Security alerts

Alert Meaning
AUDIT LOG TAMPERING DETECTED The audit log's seals don't match: an entry was changed, added or removed outside the app. Treat it as a security incident: keep the server as it is, check who has database access, and compare with a recent backup. sudo align audit:verify shows where the break is.
Unsigned update refused See Not signed with the release key above.

Still stuck? Ask in GitHub Discussions, with your version and the exact message (without client data). Security problems go privately.