Skip to main content

A privileged session will not start

Approval, policy, concurrency, MFA and gateway refusals when a session will not open, with the exact message for each, and the policy fields nothing reads.

Written for whoever runs IT9 min readUpdated

You have asked to open a privileged session — a connection to a server or device where the password is injected by the platform and never shown to the person doing the work — and it has been refused. This article lists the refusals in the order the platform applies them, gives the exact message and status for each, and then covers the gateway failures that happen after a session is authorised and still leave you looking at nothing.

The section on policy fields that are never read is the one to jump to if you are convinced your configuration is broken. Three fields on an access policy are stored, returned by the API and rendered in the console, and are read by nothing. If you set one and expected an effect, the policy is not broken — the value is simply not consulted.

The order the checks run in

Refusals are applied in a fixed order, so the first thing to fail is the only thing you are told about. Knowing the order stops you fixing the wrong thing.

  1. The request itself — well formed, and does the credential exist?
  2. Every active policy covering the credential is collected.
  3. The concurrent-session cap for that credential.
  4. Whether an approval is required, and whether the request carries one.
  5. Whether that approval is valid — right organisation, requester and credential, not already spent, not expired.
  6. Multi-factor authentication, if any covering policy demands it.

Only after all six does the session get created and handed to the gateway — which can still fail on its own account.

The request itself

Refusals before any policy is consulted
400  credential_id, target_host, and protocol are required
400  invalid protocol: must be ssh, rdp, https, or database
404  credential not found
500  failed to start session

Those four protocols are the whole list; https and database are relayed rather than proxied, and no credential is injected into them. credential not found reads in the console as We couldn't find that vault credential. and means the id does not resolve inside your organisation. A 500 means everything passed and the session could not be created: ours to fix, and worth reporting.

The concurrent-session limit

maximum concurrent sessions reached for this credential
HTTP 409 Conflict

Every policy carries a maximum-concurrent-sessions figure and the default is 1. A policy created with nothing but a name gets one hour, one concurrent session, approval required and recording on; the console says so: Unless you change them: approval is required, the session is recorded, it may last one hour, and one session may run at a time.

So the usual cause of a 409 is a colleague already in a session on that credential — or, far more often, your own abandoned session still counting. Look at the session list, find the active one, and terminate it.

Approval required, and policy denied

Approval is the default. A credential covered by any policy requiring approval cannot be checked out directly: you raise an access request, somebody approves it, and the session is started against that approval. Every message below is returned as its own text, so this is what you will read.

Approval, policy and MFA refusals
403  approval required: submit a JIT access request first
403  approval required before session can start
403  approval record is invalid for this session
403  approval record has expired
403  action violates privilege elevation policy
403  action violates privilege elevation policy: requested duration <n> min
       exceeds policy max <n> min
403  approver attestation is required
401  MFA verification required for this privileged session
500  MFA required but no verifier configured

approval record is invalid for this session means the approval does not match this organisation, requester or credential — or has already been spent. An approval is good for one session, not for a working day. approval record has expired means the grant window passed; in the console, This privileged session has expired. The duration refusal is the commonest concrete form of a policy denial, and the default maximum is 60 minutes. A 500 on MFA means a policy demands a second factor and the deployment has no verifier: it fails closed, which is right, and it is ours.

Refusals on the access-request side of the same workflow
400  credential_id and justification are required
400  action is required (approve or deny)
409  access request is not in pending status
404  access request not found
404  access request not found or not in approved status
approvals: instance <id> already <status>
approvals: instance <id> expired
approvals: role "<role>" not permitted for step <n>
approvals: user <id> already approved step <n>

Three policy fields that are now enforced

These three columns were stored, returned by the API and rendered in the console without ever being consulted when a session started. They are now evaluated at session start, and a session that violates any of them is refused with an audited reason.

allowed_time_window — enforced
A session requested outside the window is refused with privileged access is outside the policy's allowed time window. The accepted format is what the console's placeholder always showed: Mon-Fri 09:00-18:00 UTC. Day lists (Mon,Wed,Fri), a bare 09:00-18:00 for every day, overnight windows that wrap past midnight (22:00-06:00), several windows separated by ;, and an IANA timezone such as Europe/Berlin all work. Leaving it empty still means access at any time. Cron expressions are not accepted — an unparseable window is rejected when you save the policy, so you find out while the form is open rather than at 03:00.
record_session — enforced
Setting this to false now genuinely disables recording for sessions the policy governs: no recording is stored, and no keystroke index is built. The session itself is still fully audited — who connected to what, when, for how long, under whose approval — and the session row carries recording_enabled: false, so a missing recording is explained rather than looking lost. When several policies cover one credential, recording happens if any of them requires it, so an organisation-wide record everything policy cannot be defeated by adding a narrower one.
role_id — enforced
A policy naming a role now restricts the credential to members of that role within the same organisation. Anyone else is refused with privileged access requires a role the user does not hold. If the role membership cannot be checked, the session is refused rather than allowed.

Two further honesty items, because they bear on how much weight an approval carries. Approver role is not enforced on the primary approval path, and self-approval is not prevented — the person who raised a request can approve it. Where approval genuinely has to be somebody else, that is an organisational rule you enforce with people, not a control the platform applies for you today. The multi-step engine that would enforce ordered steps and quorums is invoked, its verdicts are discarded, and its state is held in memory. Do not build a process on it yet.

Authorised, and still will not connect

Past the policy checks the session becomes a listener on the gateway and waits for you. None of what follows looks like a policy problem.

Gateway and broker refusals
gateway: no operator connected within <window>
gateway: session already has a listener
gateway: no such session
gateway: session <id> did not finish within <limit>
gateway: bind listener: <error>
gateway: a vaulted credential is required; refusing to broker an un-injected session
gateway: shutting down
unsupported protocol "<value>"
dial upstream ssh: <error>

The first is by far the most common in daily use: the session was created and nobody attached in time. This is the link expired before I clicked it — start a new session. no such session is not a failure on termination, incidentally: the record is still terminated. The eight-hour limit is the only thing that ends a long-running session. dial upstream ssh means the gateway got as far as your server and the server did not answer, which is the same class of problem as an unreachable rotation target.

RDP has a richer set, because it negotiates security first and the platform will not weaken that negotiation. rdp: target host and port are required and rdp: vaulted account is required; the gateway will not proxy an un-injected RDP session are configuration; rdp: dial target <host>: <error> is network. The rest are the interesting ones:

RDP negotiation and CredSSP refusals
rdp: target refused negotiation: SSL_REQUIRED_BY_SERVER
rdp: target refused negotiation: SSL_NOT_ALLOWED_BY_SERVER
rdp: target refused negotiation: SSL_CERT_NOT_ON_SERVER
rdp: target refused negotiation: INCONSISTENT_FLAGS
rdp: target refused negotiation: HYBRID_REQUIRED_BY_SERVER
rdp: target refused negotiation: SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER
rdp: target presented no certificate; cannot bind CredSSP
rdp: target rejected CredSSP authentication: <NT_STATUS_...>
rdp: CredSSP public-key binding mismatch; refusing to delegate the credential
rdp: target refused NTLM extended session security; refusing to downgrade
rdp: Client Info PDU is RDP-encrypted; gateway requires TLS (SEC_ENCRYPT set)

Those names are the Windows server's own, passed through unedited so you can search Microsoft's documentation for them. Two lines are us refusing to proceed rather than the server refusing us, and both are deliberate: a public-key binding mismatch is what a machine-in-the-middle looks like, and downgrading NTLM would hand your administrator credential to whatever asked nicely. rdp: target rejected CredSSP authentication followed by an NT_STATUS_ name is the server rejecting the injected credential — usually the account is locked out, disabled, or lacks Remote Desktop rights. Proxied RDP sessions covers the setup that avoids most of these.

What to do

The status code tells you whose problem it is. Read it before the message.
StatusCauseWho acts
409Concurrency cap, or an approval already decidedYou, or a colleague in a session
403Approval or policyAn approver, or whoever owns the policy
401Second factor missingYou
404Credential, session or request does not existYou — check the id
400The request is malformed or the protocol unsupportedWhoever built the request
500A fault on our sideUs. Report it.
  1. Check the session list for your own abandoned session

    With a default concurrency of one, a session you walked away from blocks the next one indefinitely. This is the commonest cause of a 409 and the fastest to fix.

  2. For a 403, read every policy covering the credential

    Not only the narrowest — all of them apply. The policy list states each one's scope in words, so it is quick to spot an organisation-wide policy doing the refusing. PAM access policies explains the model.

  3. Do not tune a field from the never-read list

    If the fix you are reaching for is a time window, a recording toggle or a role on a policy, stop: those three do nothing. Change approval, duration or concurrency instead.

  4. If the gateway refused, simply start again

    Most gateway refusals are timing. A fresh session costs nothing. If the same RDP negotiation name returns twice, the problem is on the Windows host and its own event log will say more than we can.

One thing that will not be the cause: recording. Recordings are held in memory in the current build and are lost on restart, so an old one may be unavailable — recording not available, 404 — but a missing recording never prevents a new session starting. Download what you need while a session is fresh; see Session recording and transcripts.

Was this article wrong?

If a procedure here does not match what you see, or a limit we described has changed, tell us and we will fix the page. Email us about this article, or see how to get help if you need an answer rather than a correction.

Everything in troubleshooting