Skip to content

Troubleshooting

Start with the smallest failing layer: process, local listener, public TLS route, SAML flow, session, and finally the backend. Keep the instance name, timestamp, and error-page request ID available while investigating.

Protect diagnostic data

Logs can contain user identifiers, client addresses, complete request paths with query strings, referrers, and user agents. Never publish session cookies, SAML responses, passthrough tokens, the dynamic JSON file, or private keys.

Quick triage

SymptomFirst check
Service will not startsystemctl status and the first fatal log message
Public URL is unreachableLocal listener, edge proxy, DNS, and TLS certificate
Repeated redirectsdomain, public Host, HTTPS, cookies, and system time
SAML error pageIdP metadata, Entity ID, ACS URL, signing, and NameID/attributes
403 after SAML loginEmail, sAMAccountName, or NameID is missing or empty
502 Proxy Errorproxy.targetURL, backend reachability, and target TLS trust
“Loop Detected”targetURL points back to PassBeyond or its public origin
Missing identity headersSession validity, claim mappings, and direct backend access
Wrong client IPEdge header overwrite and trustedProxies
Logout immediately logs in againIdP session remains active or SLO is not advertised
Public route is unexpectedly openpassthroughPaths prefix or a valid passthrough token

Collect a safe baseline

Replace myapp and the public hostname throughout these examples:

bash
sudo systemctl status passbeyond@myapp.service
sudo journalctl -u passbeyond@myapp.service --since "15 minutes ago" --no-pager
sudo ss -ltnp | grep 8123
curl --fail --show-error https://myapp.example.com/saml/metadata.xml
curl --fail --show-error https://myapp.example.com/saml/certificate.crt \
  | openssl x509 -noout -subject -issuer -serial -dates -fingerprint -sha256

The metadata check proves basic HTTP availability, not a complete login or backend request. See Logging and monitoring for log categories and safe evidence collection.

Service does not start

Configuration file cannot be loaded

Typical messages include Failed to load configuration, Domain not set, or a YAML parsing error.

Check:

  • the systemd instance name maps to /etc/passbeyond/<instance>.yaml;
  • the file is readable by the passbeyond user;
  • domain, one IdP metadata source, proxy.listenAddress, and proxy.targetURL are set;
  • indentation uses spaces and nested proxy settings are below proxy;
  • domain contains a hostname without https:// or a path.

Test file access without printing the contents:

bash
sudo -u passbeyond test -r /etc/passbeyond/myapp.yaml

PassBeyond first attempts a complete environment configuration. An incomplete environment set falls back to YAML rather than merging with it. Review configuration loading when systemd overrides or container variables are present.

Dynamic configuration cannot be written

Messages such as Failed to save dynamic configuration usually indicate a missing directory, incorrect ownership, a read-only mount, or two instances using the same file.

bash
sudo install -d -o passbeyond -g passbeyond -m 0750 /var/lib/passbeyond
sudo -u passbeyond test -w /var/lib/passbeyond

Every instance needs a unique configPath. Do not replace a dynamic file just to bypass a permission error: doing so rotates session and SAML keys.

Listener cannot start

bind: address already in use means another process or PassBeyond instance owns the configured address. Inspect it with:

bash
sudo ss -ltnp

Give each instance a unique proxy.listenAddress. A port below 1024 also requires privileges that the packaged service intentionally does not have.

IdP metadata problems

Remote metadata fails on first start

The first start needs either a successful idpMetadataURL download or an already valid cache. Verify DNS, outbound HTTPS, the remote status code, system CA trust, and any HTTPS_PROXY or NO_PROXY settings.

bash
sudo -u passbeyond curl --fail --show-error \
  https://sso.example.com/path/to/metadata.xml >/dev/null

PassBeyond accepts only an HTTP 200 response, uses a 30-second timeout, and reads at most 10 MiB. A truncated, HTML, or otherwise invalid response fails XML parsing.

Cached metadata is used

A startup warning that refresh failed but cached metadata was loaded is an availability fallback, not a healthy steady state. Restore access to the metadata endpoint and confirm a later SAML IdP metadata updated and cached log message.

Local metadata does not update

idpMetadataFile is read only during startup. Replace the file atomically, verify ownership, and restart the instance. Local mode does not use the remote cache or the 30-minute refresh loop.

Login redirect loop

A loop between the application and /__passbeyond-redirect usually means the application cookie is absent or rejected.

Check all of the following:

  1. The browser uses https:// and accepts cookies.
  2. domain exactly matches the public hostname.
  3. The edge proxy preserves the public Host and overwrites X-Forwarded-Proto with https.
  4. Server, IdP, proxy, and client clocks are synchronized.
  5. The browser does not exceed its cookie-size limit because of excessive claims or groups.
  6. The public request returns to the same hostname and HTTPS port used before login.

Inspect browser developer tools for __passbeyond_session. Do not copy its value into an issue or chat.

SAML authentication fails

Compare the IdP application with the endpoint reference:

IdP settingExpected value
Entity IDhttps://<domain>/saml/metadata
ACS URLhttps://<domain>/saml/acs
SLO URLhttps://<domain>/saml/slo
NameID formatTransient

Then verify:

  • responses and assertions use the expected signing configuration;
  • the IdP metadata contains the current signing certificates;
  • encrypted assertions use the certificate currently served by PassBeyond;
  • samlRequestSigning matches whether the IdP expects signed authentication requests;
  • the IdP sends email, sAMAccountName, or a non-empty NameID;
  • the assertion validity window agrees with synchronized system time.

Use the request ID displayed on the error page to locate the corresponding SAML-ERROR log record.

SAML succeeds but PassBeyond returns 403

PassBeyond chooses the subject from email, then sAMAccountName, then SAML NameID. If all are empty, it responds with SAML session has no usable subject identifier.

Add one of the supported aliases from the claims reference. Prefer a stable email or account name. A transient NameID may change at the next authentication and is a poor backend identity by itself.

Backend returns 502

Test the target from the PassBeyond host or container network:

bash
curl --fail --show-error http://127.0.0.1:8888/

Check the scheme, host, port, DNS, firewall, and target certificate chain. Keep targetDisableSSLVerify: false; install the correct CA rather than permanently bypassing verification.

The error page request ID matches a PROXY-ERROR record containing the underlying network error.

Loop detected

PassBeyond adds X-Passbeyond-Instance-ID and rejects a request that returns to the same instance. This normally means proxy.targetURL points to:

  • the public PassBeyond hostname;
  • the edge proxy route that sends traffic back to PassBeyond;
  • another proxy rule that loops to the same listener.

Point targetURL directly at the backend's private origin.

Backend headers are missing or unexpected

Confirm the request is authenticated rather than allowed through a passthrough rule. Then verify that the backend is reached only through PassBeyond.

PassBeyond removes its own session cookie and client-provided identity headers before adding trusted values. The backend should inspect headers case-insensitively. Multi-valued groups arrive as one comma-separated value.

If X-Passbeyond-User exists but an attribute header does not, compare the IdP's emitted attribute name with the claim aliases. Empty attributes are intentionally omitted.

For Basic-auth integration, proxy.useBasicAuth sends the subject with an empty password. It does not emulate a form login and may not work with applications that require a real password.

Client IP is incorrect

PassBeyond trusts X-Forwarded-For only when the direct peer matches proxy.trustedProxies. It uses the first forwarded address and then overwrites both X-Forwarded-For and X-Real-IP for the backend.

Avoid broad network ranges. Configure the exact edge proxy IP or narrow container subnet, and make the edge proxy overwrite client-supplied forwarding headers.

Passthrough access is too broad

passthroughPaths uses literal prefix matching. /api also matches /api-admin. Prefer a trailing slash such as /api/, test neighboring paths, and never configure /.

Passthrough tokens apply to the entire instance and use:

http
X-Passbeyond-Authorization: Bearer <token>

Rotate a token immediately if it appears in a log, shell history, ticket, or diagnostic capture.

Logout behavior

/saml/slo always clears the local PassBeyond cookie. When the IdP advertises SLO, PassBeyond also starts or processes the IdP logout flow. Without an IdP SLO endpoint, the IdP session remains active and may immediately authenticate the browser again on the next request.

Logout cannot revoke a copied PassBeyond JWT. See Sessions.

Large sessions and headers

All mapped attributes and groups are stored in the browser JWT. Large group sets can exceed browser cookie or edge proxy header limits even though PassBeyond itself permits up to 1 MiB of request headers.

Reduce the attributes and groups emitted by the IdP. Typical symptoms are a missing cookie, 400/431 responses, or a login loop immediately after a successful assertion.

Preparing a support report

Include:

  • PassBeyond version or package version;
  • deployment type and operating system;
  • IdP and backend product versions;
  • exact UTC timestamp and request ID;
  • sanitized relevant log lines;
  • redacted static configuration with domains generalized if necessary;
  • expected and actual behavior.

Never include the dynamic JSON file, cookies, SAML assertions, authorization headers, passthrough tokens, private keys, or complete metadata containing internal details.

Released under the MIT License.