Troubleshooting
Find the cause of a pfSense Actions problem by checking the container first, then the HTTP status, then the console.
Start with Container State
docker compose ps
docker compose logs --tail 100 app
docker compose top
A healthy container shows healthy, logs Listening on port 22603, and runs node build/index.js under /init. Repeated startup errors in the logs mean s6-overlay keeps restarting a service that fails as it starts.
Match the HTTP Status
| Status | Likely cause | Where to look |
|---|---|---|
400 | The body is invalid, or Content-Type: application/json is missing. | Bodies Get 400 |
401 | The token is missing, mistyped, expired, or revoked. | Tokens Get 401 |
403 | The token lacks the route's scope, or the route belongs to the console and needs a browser session. | A Valid Token Gets 403 |
404 | The path or method is wrong. | Request Basics |
413 | The body is over 64 KB. | Request Basics |
429 | The client reached a rate limit. | Every Client Gets 429 |
500 | An unexpected error, logged as an ERROR line. | Container State |
502 | The SSH sign-in or the command failed. | Requests Get 502 |
503 | No connection is saved, its credential was removed, or the target never met the reachability condition. | Requests Get 503 |
Every error response also carries an error.code, listed in Status Codes and Limits.
Startup Failures
Environment Validation Fails
pfSense Actions checks its settings before it starts listening, and a failed check ends startup with an error that names the setting's internal field.
| Field in the error | Fix |
|---|---|
pfsenseSshIp | Use an IP address in PFSENSE_SSH_IP, not a hostname, or leave every PFSENSE_* value empty. |
pfsenseSshPort | Set PFSENSE_SSH_PORT to a number from 1 to 65535. |
The PFSENSE_* values go together, so set PFSENSE_SSH_IP, PFSENSE_USERNAME, and PFSENSE_PASSWORD or PFSENSE_PRIVATE_KEY, or leave all of them empty.
Encryption Key Doesn't Match
The encryption key at /data/keys/installation.key doesn't belong to this database.means the key file comes from another database, for example after a restore that mixed files.The encryption key file at /data/keys/installation.key is not 64 hexadecimal characters.means the key file is damaged.
Backup and Recovery covers the way out. A missing key file doesn't stop startup, as described in Lost Encryption Key.
PUID, PGID, or TZ Rejected
The container's setup step stops with messages such as PUID must be a positive integer., PGID must be between 1 and 2147483647., or Unknown timezone: .... A value of 0 is rejected so the service can't run as root, and TZ has to name a zone in the image's time zone database.
Permission Errors on the Data Folder
An EACCES error for /data or the database files means they belong to a different user than PUID and PGID. Change their owner as described in Backup and Recovery.
Build Stops on the Architecture
Unsupported target architecture: ... means the build targeted a platform other than amd64 or arm64. Build on, or for, one of those two.
Request Failures
Every Client Gets 429
- Clients share one address when the proxy doesn't send
X-Forwarded-For, or when the clients are behind the same NAT. - Wait for the
Retry-Afterseconds, then check the proxy setup in HTTPS Reverse Proxy.
Tokens Get 401
- The token was revoked or has expired, which the Access tokens page shows.
- The header isn't exactly
Authorization: Bearerfollowed by the fullpfa_token, for example because the scheme is missing or extra characters slipped in.
A Valid Token Gets 403
Compare the route with the token's scopes on the Access tokens page. The connectivity and system information routes need pfsense:read, the ping route needs reachability:read, and the Wake-on-LAN route needs wol:execute.
The code session_required means the route belongs to the console, such as the notification routes, and no token works there. A script can sign in the way the console does instead, as described in Notifications.
Requests Get 502
pfsense_unavailable— The IP address, port, username, or credential is wrong, SSH is turned off in pfSense, or a firewall rule blocks the host that runs pfSense Actions.command_failed— The account can't run the command, or the system information route got output it couldn't parse.
The logs don't record the cause. Select Test connection in the console to check the sign-in alone, then run the command yourself as shown in Prepare pfSense.
Requests Get 503
connection_not_configured— No pfSense connection is saved yet, or its password or private key was removed with a lost encryption key. Set one up, or enter the credential again, on the console's Connection page.target_unreachable— Every ping attempt finished without meeting the selected condition, which in normal mode means no reply arrived and in strict mode also covers partial replies. Retry later, raisecount, or turn off strict mode when partial replies are enough.
Bodies Get 400
error.issues names each field that failed and why. The usual causes are:
Content-Type: application/jsonis missing from the request.countis a string, or it's outside 1 to 10.- The MAC address uses hyphens or mixed case.
- An address is a hostname rather than an IP address.
Console Problems
The Setup Code Is Rejected
- The code expired, because each one lasts 30 minutes. Restart the container with
docker compose restart appand use the new code from the log. - The code was already used. Once an account exists, the console shows the sign-in screen instead.
- After 10 wrong codes in 15 minutes, the setup screen refuses more from that address until the window passes.
Credentials Are Rejected
- Only the administrator account signs in here, so tokens and pfSense logins don't work.
- After 10 failed attempts in 15 minutes, the console refuses sign-ins from that address until the window passes.
Lost Authenticator or Password
Sign in with a recovery code or a passkey, or follow Backup and Recovery.
Saved Secrets Were Removed
The console shows Saved secrets were removed when pfSense Actions started without its encryption key, and the log has a warning that starts with No encryption key was found at. Enter each listed item again, including the secret fields of each notification destination, as described in Lost Encryption Key.
Signed Out Unexpectedly
A browser session ends 24 hours after sign-in, and changing the password on another device ends this one. Signing in again is all it takes, and nothing else is lost.
Passkeys Aren't Offered
- The console is open at an IP address such as
127.0.0.1or192.0.2.10, or over plain HTTP on a name other thanlocalhost. Open it at its HTTPS domain name. - The proxy doesn't send
X-Forwarded-Proto, so pfSense Actions thinks the browser used plain HTTP. Check the proxy setup in HTTPS Reverse Proxy.
Passkey Sign-In Fails
- The passkey was added at a different hostname, and it only works there. The Passkeys list shows each one's hostname.
- The browser or password manager doesn't have the passkey anymore. Sign in another way, remove it, and add it again.
Notification Problems
A Test Fails
The destination's row shows The test couldn't be sent: and the reason.
HTTPand a4xxstatus — The service refused the alert, usually because a token, key, chat, room, or webhook URL is wrong or was revoked. Select Edit, enter the field again, and send another test.No answer within 10 seconds.— pfSense Actions couldn't reach the service in time. Check that the Docker host can reach the service's address, and that a self-hosted server is running.- A network or mail error — The address doesn't resolve or refuses the connection, or the SMTP server rejected the sign-in or the Security choice. TLS usually goes with port 465, and STARTTLS with port 587.
Alerts Don't Arrive
- The event isn't checked — Select Edit and check it. Action failed and Wake-on-LAN sent start unchecked.
- The destination is paused — A row that ends with
Alerts are paused until you do.lost its secret fields with the encryption key. Enter them again as described in Notifications. - The last attempt failed — Alerts aren't sent again, so the reason after Last attempt failed shows what to fix, and Send test confirms the fix.
pfSense Can't Be Reached Never Arrives
- The scheduled check runs only while a destination that isn't paused chose pfSense can't be reached or pfSense reachable again, and while the connection's password or private key is saved.
- The first check runs 5 minutes after pfSense Actions starts, and it takes two failed checks in a row, so the alert can take about 10 minutes.
- When pfSense is also the router for the Docker host, the outage can keep the alert from reaching a cloud service. A destination on the same network still gets it, as described in The Scheduled Check.
Changed Settings Had No Effect
- The deprecated
PFSENSE_*values are bootstrap values, so they only matter while no connection is saved, and every start logs a warning while they're set. Change the connection in the console instead, and remove them. LOG_LEVELandLOG_TIMEapply at the next start, so recreate the container after changing them.- The container fixes
PORTat22603andDATA_DIRECTORYat/data, so changing them has no effect in Docker. - In a source run, pointing
DATA_DIRECTORYsomewhere new starts an empty database with a new encryption key, where the setup screen and the bootstrap values apply again.