Skip to main content
Version: Next 🚧

Troubleshooting

The golden rule: the Workspace CR tells the story. Phase, conditions and Events carry every admission decision, denial reason and teardown failure — start with:

kubectl -n <cr-namespace> describe workspace <name>

Workspace is denied at creation​

Denials read [ReasonCode] human message — in the kubectl error, the HTTP 403, the Ready condition and the portal alike.

ReasonMeaningFix
NoPolicyMatchesno WorkspacePolicy matches youship a default policy at priority 0; check your IdP groups are mirrored (they sync at SSO login)
ImageNotInCatalogthe template's image has no WorkspaceImage entryadd/approve the catalog entry with the exact ref
ImageDisabledcatalog kill-switch is offre-enable the wsi
ImageNotAllowedallowedGroups or the policy's image subset excludes youcheck the policy's images and the image's allowedGroups
ProtocolMismatchtemplate declares a protocol the image doesn't servealign protocols with the WorkspaceImage.protocols
ResourcesOutOfBoundssizing outside image min/max or policy capspick a size within bounds
QuotaExceededcount, running count or aggregate over the policy limitdelete/pause something, or raise the policy. "running workspace quota reached" also denies resume — expected with maxRunningWorkspaces, pausing another workspace frees the slot (or create the workspace paused)
IdentityViolationspec.owner ≠ your authenticated user, or forged identity annotationsset owner to your own username; never set waas.xorhub.io/* identity annotations
OverrideNotAllowedan override field is not delegated to youtemplate ∩ policy overrides.allowedFields must contain the field

A user whose group mirror is empty matches only subjects-less policies — that's the "everyone gets the default policy" symptom, not a priority bug: groups sync from the IdP at every SSO login (or via admin edit).

Workspace Running but not connectable​

  • Ready=True but ConnectionReady=False: the pod runs but the desktop server doesn't listen yet (or crashed). Check the pod logs in the target namespace.
  • The desktop container refuses to start without WAAS_DESKTOP_PASSWORD — under the platform this is injected automatically; standalone/custom setups must provide it. Legacy VNC_PW/RDP_PASSWORD are refused with an explicit error.
  • Placed template + CreateContainerConfigError: a template secretKeyRef resolves in the target namespace — provision the Secret there. See Placement.
  • PullSecretMissing condition: the WorkspaceImage's imagePullSecretRef points at a missing Secret — fail-closed, retried automatically once fixed.

Video works, no sound​

enable-audio alone is not enough over VNC: the template's vnc protocol entry also needs exposeAudioPort: true (opens PulseAudio's 4713 on the container and Service). Without it the session degrades silently. See Templates and protocols.

Workspace stuck in Terminating​

Read the TeardownFailed event/condition on the CR — the finalizer retries forever rather than leak silently. Full procedure, including the last-resort finalizer bypass: Workspace deletion.

Paused workspace didn't come back on schedule​

Remember the arbitration rule: a manual action wins until the next scheduled edge of the opposite kind. A manual pause during an uptime window stays down until the next scheduled start — that's the contract, not a missed cron. See Workspace lifecycle.

Where the logs are​

ComponentWhat you'll find
operatorreconcile decisions, admission re-checks, teardown/janitor activity
api-serverauth, policy resolution, audit trail, session sweeper
wwtsession/JWT validation, guacd handshakes
desktop podXvnc/xrdp/sshd/supervisord logs, entrypoint warnings (e.g. RDP auth disabled)

All in the platform namespace (kubectl -n waas logs deploy/...), desktop pods in their target namespace.