Troubleshooting#
Start with the logs: journalctl -u hapman -n 50 for HAPMan and journalctl -u haproxy -n 50 for HAProxy. The Audit page shows every apply, including rejected and failed ones, with HAProxy's error.
Status and routing#
Servers show "not live" straight after an apply#
HAProxy has just reloaded and HAPMan read its status before the new processes had the servers. Refresh the page after about 20 seconds: by then the first health checks have run and the servers show UP.
If a server stays not live, check the route is enabled and the apply succeeded (look for an apply entry in the Audit log). "Live status unavailable" at the top of the page means HAPMan can't reach HAProxy's admin socket; that's normal before the first apply.
A server shows DOWN#
Hover over the DOWN pill to see the last check result.
| Check result | Meaning | What to do |
|---|---|---|
| L4CON | Connection refused | Usually a firewall or VLAN rule between the HAProxy VM and the server, or the service isn't listening on that port. Test from the VM: nc -vz 192.168.10.11 443. |
| L4TOUT | Connection timed out | Almost always a firewall or VLAN rule dropping traffic, or the wrong IP. Same test as above. |
| L7STS | Connected, but the page didn't return 200 | A health page problem: the path is wrong, or the server is unhealthy. For Exchange, check /owa/healthcheck.htm and whether the server is in maintenance mode. Test from the VM: curl -k -i --resolve mail.contoso.com:443:192.168.10.11 https://mail.contoso.com/owa/healthcheck.htm |
| L6 errors | The TLS handshake for the check failed | The backend isn't speaking TLS on that port. Use port 443 for HTTPS routes, or switch the check to TCP connect. |
Clients get the wrong server, or the connection is closed#
- Check the hostname is on the right route. HTTPS routes match the name the client asks for exactly, or by
*.wildcard. - With no Default route, HTTPS connections for names no route matches are closed. Very old clients that don't send SNI land on the default route too.
- Check the router forwards 443 (and 80) to the HAProxy VM, not to an old server.
Applying changes#
"no new privileges" when applying (versions before 1.1)#
Applying fails with an error that sudo can't run because the "no new privileges" flag is set. The hapman.service file in 1.0.x had systemd hardening that stops HAPMan using its one sudo rule.
Update to the latest version, which installs the fixed service file. Or copy it in yourself:
sudo cp /opt/hapman/deploy/hapman.service /etc/systemd/system/hapman.service
sudo systemctl daemon-reload && sudo systemctl restart hapman
(If /opt/hapman is still 1.0.x, copy deploy/hapman.service from the new zip instead.)
"Not applied. The live config has not changed"#
HAProxy rejected the new config, or the reload failed and the previous config was put back. The message under it is HAProxy's own error. Common causes:
- a TCP route on a port something else on the VM already uses,
- a backend hostname the VM can't resolve. Use an IP address, or fix DNS on the VM.
Fix the route and apply again. Nothing changed in the meantime.
"Form expired"#
Your session ended or the page was open too long. Refresh the page and try again. Sessions last 8 hours.
Install and sign-in#
"Assembly with same name is already loaded"#
New-HAPManApp.ps1 stops with this error when a different version of the Microsoft Graph modules is already loaded in that PowerShell session, often from your profile or an earlier command. Graph's modules all have to be the same version.
Open a new PowerShell window, or start one without your profile, and run the script again:
The setup code is rejected#
| Message | Fix |
|---|---|
| "That doesn't look like a HAPMan setup code (it should start HAPMAN1.)" | You pasted something else, such as the client ID. Copy the line under HAPMan setup code in the script's output. |
| "The setup code is damaged or incomplete" | Part of the line is missing. Copy the whole line in one go: it's long, and some terminals wrap it. Line breaks and spaces are ignored. |
| "The app was registered for …, but this server is …" | The code was made for a different hostname or port. It's a warning: run the script again with -HostName and -Port matching what you gave the installer, then sudo ./install.sh --entra. |
If it still won't take, answer n to Try pasting it again? and enter the values by hand (the script's -ShowValues switch prints them).
Redirect URI mismatch when signing in#
Entra ID shows AADSTS50011: the redirect URI doesn't match. HAPMan's address (hostname or port) isn't one the app registration knows, usually after --reconfigure.
Run New-HAPManApp.ps1 again with the new -HostName and -Port; it adds the new redirect URI to the app. Then run sudo ./install.sh --entra and paste the new code.
Signed in to Entra, but HAPMan says no#
| Message | Fix |
|---|---|
| "Your account does not have the 'HAPMan.Admin' app role for HAPMan." | Assign the account, or a group it's in, the HAPMan Admin role in Enterprise applications > HAPMan > Users and groups, then sign in again. |
| "… is not on the HAPMan allow-list." | You set an allow-list of UPNs (option 3). Add the UPN to HAPMAN_ALLOWED_USERS in /etc/hapman/hapman.env and restart HAPMan. |
| "This account is not from the permitted tenant." | You signed in with an account from another tenant, such as a guest's home account. |
The Audit log records each denied sign-in with the reason.
HAPMan won't start on port 443#
Older installs let you choose port 80 or 443 for HAPMan, which clash with HAProxy. The installer now refuses them and stops with "HAPMan is set to port 443, which HAProxy needs for your routes". Run:
Choose 8443 (or another port from 1024 up), then update the Entra redirect URI as above.
The Let's Encrypt certificate fails#
- Check the Cloudflare token has Zone · DNS · Edit on the zone HAPMan's name is in.
- Check the name is in that zone.
- To get going while you sort it out, run
sudo ./install.sh --self-signed, then--reconfigurelater.