TROUBLESHOOTING

When something does not connect

Start with the journal, then match the line or the error code you see against the tables below. Every entry says who can fix it: the gateway operator, the target's owner, or the user.

Where the logs are

The gateway logs to stderr, which systemd collects. The audit log is not a file: it lives in the database, hash-chained, and is read on the Events and Recordings pages of the admin console (the Audit portal, for an auditor-only account) or exported to your SIEM. Recordings are files under the data directory.

sudo journalctl -u zanskar -n 200 --no-pager     # the last 200 lines
sudo journalctl -u zanskar -f                    # follow live while you reproduce a problem
sudo journalctl -u zanskar --since "10 min ago" -p warning   # warnings and errors only
sudo journalctl -u zanskar -o cat | grep request_id=<id>     # one request, when a user reports an error id
sudo docker logs guacd --tail 100                # the desktop relay, if RDP/VNC misbehave
ls -la /var/lib/zanskar/recordings | tail        # recordings land here as sessions end

Compose: docker compose -f deploy/docker-compose.yml logs -f zanskar and ... logs guacd. For more detail set the log level to debug on the console's Settings page (applies at once, no restart; Reset afterwards), or ZANSKAR_LOG_LEVEL=debug in the env file and restart. The console's Logs page shows the last 2,000 lines from memory, filterable and downloadable, when you have no shell on the host.

Journal lines and what they mean

LineMeaningFix
listening without TLS; acceptable only behind a TLS-terminating proxy on loopbackBehind-proxy mode: the gateway speaks plain HTTP on loopback and expects your proxy on 443.Expected. If you meant the gateway to serve TLS itself, re-run zanskar init -force with -tls-cert and -tls-key.
no admin user exists; create one with `zanskar admin create`Migrations ran but the first admin was never created.Run the admin create line from the install page as the service user.
The console says Restart required, or Cannot check /etc/zanskar/envA boot setting changed in the env file after the gateway started; boot settings apply only to a fresh process. The second message means the service user cannot read the file.Use the banner's Restart the gateway (waits for live sessions, then systemd restarts it). For the second: chgrp zanskar /etc/zanskar/env && chmod 0640 /etc/zanskar/env.
guacd dial failed ... connection refusedThe desktop relay is not running at ZANSKAR_GUACD_ADDR. The package does not install it. Users see the desktop service (guacd) is not running.Start guacd, check the address in /etc/zanskar/env, restart the gateway.
guacd dial failed ... expected ready (or an error from guacd)guacd answered but could not reach the machine: RDP or VNC disabled, port closed from the gateway, or the certificate pin no longer matches. Users see could not open a connection to the machine.Open 3389 or 5900 from the gateway host, confirm the service on the target, probe the target again after a certificate change; read docker logs guacd for the underlying reason.
ssh dial failed ... host key mismatchThe target's SSH host key changed after it was trusted. An audit event target.hostkey.changed was written.Verify the new fingerprint with the machine's owner, then probe and trust it again in the target drawer. Do not trust an unexpected change without investigating.
ssh dial failed ... authenticationThe bound credential is wrong for this host, or the login user does not exist there.Check the credential's username and material; for SSH-CA mode, that the host trusts the CA.
key ring: keyring: cannot unwrap key version N with the configured KEKThe service started with a master key that is not the one the data keys are wrapped under: the environment was not updated after zanskar key rotate-master, or a restored backup belongs to a different installation.Put the key that rotate-master wrote (or the escrowed one for that backup) in /etc/zanskar/env and restart. Nothing is lost while the right key exists.
open credential ... could not be openedA stored secret failed to decrypt: the master key in the environment is not the one that sealed it.Restore the original ZANSKAR_MASTER_KEY from escrow. If it is gone, re-enter the credentials.
instance connect push failedEC2 Instance Connect refused the one-time key: the role lacks ec2-instance-connect:SendSSHPublicKey, or the instance has no ec2-instance-connect package.Fix the role's permissions policy (the IAM setup panel shows it) or the instance's packages.
recording could not be startedThe recordings directory or bucket is not writable, or (with S3 storage) the local spool folder is not private; the session is refused rather than run unrecorded.Check ZANSKAR_RECORDINGS_DIR ownership (the service user) or the S3 credentials. If the journal says recording: spool … is owned by another user, … is writable by other users or … is not a directory, someone else made the default spool under /tmp: set ZANSKAR_RECORDINGS_SPOOL_DIR=/var/lib/zanskar/spool in /etc/zanskar/env and restart.
audit chain broken at event NAn audit row was altered or removed after it was written, or written by a build whose hashing differed.Treat as an incident: restore from a backup taken before N and compare, and review database access.

Error codes the browser or API returns

CodeMeaningFix
wrong version number (from curl or a browser, not the gateway)You spoke TLS to a plain-HTTP listener: the gateway is in behind-proxy mode.Use http://127.0.0.1:8443/readyz on the host, and your proxy's https:// address from outside.
csrf_invalidA state-changing request without the session's X-CSRF-Token, or whose Origin does not match the gateway's host, typically a reverse proxy rewriting Host.Make the proxy pass the original Host (Caddy and nginx proxy_set_header Host $host do); reload the page to refresh the token.
mfa_required, mfa_required_by_policyThe sign-in still owes a second factor, or the policy demands an enrolled authenticator.Finish enrolment; admins can reset a lost authenticator with zanskar admin reset-mfa.
review_onlyThe account holds only the auditor role, which cannot see or connect to targets.Grant the user role as well if this person should connect; auditors review only.
policy_deniedNo enabled policy grants this user this protocol on this target right now (selector, protocol list or time window).Check the policy's targets or tags, protocols and time windows, and the user's group membership.
approval_requiredThe only policy covering this target requires approval and there is no active grant.Request access from the Targets page; an administrator approves under Approvals.
duplicate_request, already_granted, not_extendableOne open request per target and protocol: one is pending, a grant is already active (extend it instead), or the extension names something that is not your active grant.Wait for the decision, or use Extend on My access.
host_key_untrusted, host_key_unverifiedThe SSH host key has not been trusted yet (or, for an autoscaling instance, not yet captured).Probe and trust in the target drawer; for instances, wait for the next sync.
certificate_unpinnedThe RDP or WinRM certificate has never been captured.Probe the target once; the fingerprint is pinned from then on.
certificate_mismatchThe target presented a different certificate from the pinned one.Expected after a renewal: probe the host again. On an autoscaling instance the pin is never replaced, so the instance goes unhealthy until the group replaces it.
not_authorizedThe WinRM credential authenticated and was then refused a shell.Make the account a local administrator on the target. Remote Management Users does not cover the WinRS shell Zanskar opens. See the guide.
tls_requiredWinRM was configured on 5985 (plain HTTP), which Zanskar never uses.Create the HTTPS listener on 5986 (guide) and set the port to 5986.
invalid or expired ticketThe WebSocket came too late, was reused, or came from a different address than the connect request.Reload and connect again. If it repeats behind a proxy, make sure the proxy forwards a consistent client address (ZANSKAR_TRUSTED_PROXIES).
no_credential, credential_requiredNo credential is bound to this protocol on the target, or the target uses your own account and you did not supply it.Bind a credential in the target drawer, or enter your username and password when asked.
engine_unavailableThe target's database engine has no credential-holding sidecar in this build (a target enrolled by an older API client with an engine this version does not know).Re-enrol the target with engine postgres, mysql or mariadb.
in_use (on delete)A policy still names the target or group by id, or a session is open on it.Remove it from those policies and end the sessions, then delete again. History is kept either way.
address_forbiddenThe target address is loopback, link-local or the gateway's own, which the probe refuses.Enrol the machine's real address.
no_healthy_instancesThe autoscaling group has no instance that is in service, passing its checks and pinned.Sync the group and read its instance list for the reason per instance.
login_user_not_permittedThe SSH certificate authority on this target only issues certificates for the login users on its allowlist, and you (or the credential's fixed username) are not one of them.Add the login user to the authority's allowlist in its Setup panel, or clear the list.
not_certificate_authority, no_rotation, rotation_pendingA certificate login test on a target whose SSH slot is not an authority; a cut-over or retire with nothing prepared; a second prepare while one is pending.Bind an ssh_ca credential first; follow the rotation steps in order.
password_change_requiredThe account was created or reset with a one-time password that must be replaced before anything else.Sign in with the one-time password and set your own; the second factor comes after.
boot_settingThe setting is fixed at install and cannot be changed from the console.Edit the named variable in /etc/zanskar/env; the console then shows Restart required.
tls_proxyThe TLS card was used in proxy mode, where the gateway serves no certificate.Manage the certificate on the proxy, or set ZANSKAR_TLS_MODE=managed and restart.
test_unavailable, assume / describe / group stagesAn autoscaling access test: no cloud provider is configured, or the failing stage of the test: the trust policy or ExternalId, the permissions policy, or no such group in that region.Fix the named stage; the gateway's own role must also be allowed sts:AssumeRole on the customer role.

Reaching the gateway, certificates and the HTTP redirect

Install and startup

RDP, VNC and guacd

WinRM

Active Directory and LDAP sign-in

Certificate logins

Database sessions