What does an OpenID Connect authentication request with `prompt=none` ask for, and what comes back when it cannot be satisfied?
answer
- no interface at all, either way
- the error is the answer
- four codes, one redirect back
- none may not be combined
- unbounded retry makes the loop
basics
~10 sprompt=none forbids the provider from displaying any authentication or consent interface: answer from an existing session or return an error. The usual errors are login_required, interaction_required, consent_required and account_selection_required, delivered to the redirect URI.
solid answer
~50 s`prompt=none` tells the provider it MUST NOT display any authentication or consent interface for this request. Either an existing session at the provider satisfies it and a normal response comes back, or the request fails with an error delivered to the registered redirect URI — typically `login_required` when the user is not authenticated there, `interaction_required` when some other interaction is needed, `consent_required` when consent is missing, or `account_selection_required` when the user would have to choose an account. That makes it the standard existence check: a way for a relying party to ask "is this person already signed in at the provider?" without interrupting them. The `none` value may not be combined with any other `prompt` value, since asking for no interface and for an interface at once is contradictory. Treating the error as a normal outcome, not a fault, is what keeps the check from becoming a redirect loop.
code
http · 5 linesGET /authorize?response_type=code&client_id=lab-cases
&redirect_uri=https%3A%2F%2Fcases.example%2Fcb
&scope=openid&state=af0ifjsldkj&nonce=n-0S6_WzA2Mj
&prompt=none&id_token_hint=eyJhbGciOi... HTTP/1.1
Host: provider.examplego deeper
Recall that this value forbids the provider from showing anything, so the request either succeeds from an existing session or comes back as an error — and that the error is an ordinary answer.
Explain where the error is delivered and which codes appear, why the value may not be combined with another, and how a previously issued ID token names the user a silent request is about.
Describe the redirect loop concretely: the expected error routed into a retry path, no attempt cap, and the browser bouncing. Then give both fixes and how you would detect it in production.
Weigh silent checks as a design position: they trade a quiet round trip per navigation for a smoother experience, and they couple your sign-in behaviour to a provider's session policy you do not control.
## What the value asks for `prompt=none` is the strongest constraint the `prompt` parameter can express: the provider **MUST NOT display any authentication or consent user interface** while processing this authentication request. The provider has exactly two ways to comply. It can answer the request from a session the end user already holds there, returning a normal successful response. Or, if it cannot do that without showing something, it must return an **error**. That second branch is not a failure mode bolted on to the feature — it *is* the feature. A relying party that sends `prompt=none` is asking a yes-or-no question and has arranged for both answers to be cheap. ## The existence check The common deliberate use is to find out whether the person is already authenticated at the provider without interrupting them. A dental laboratory's case-tracking site can use it when a practice's browser arrives with no local application session: rather than dropping the user on a sign-in page, it asks the provider quietly, and only sends them through a visible sign-in if the answer is no. The same shape is used to obtain a current response for a user whose local session is about to lapse. In both cases the point is identical: **the error is an answer**, and the caller must be written to expect it as often as the success. ## The error codes The errors arrive the same way any authentication error does — at the registered `redirect_uri`, with the `state` echoed back, not as an HTTP error status from the `authorization_endpoint`. | Error code | Returned when | |---|---| | `login_required` | the provider would have to authenticate the end user, and may not display a UI to do it | | `interaction_required` | some interaction other than authentication is needed before the request can complete | | `consent_required` | consent for the request is needed and may not be asked for | | `account_selection_required` | the end user would have to choose which account to continue with | These codes are not exclusive to `prompt=none`; `login_required`, for instance, is also the typical code when a provider cannot honour `prompt=login`. What `none` changes is how routine they become. ## `none` stands alone `prompt` is a space-delimited list, so `login consent` is a perfectly legitimate request. `none` is the exception: a request that carries `none` together with any other value is an error, because it simultaneously forbids and demands an interface. If a code path builds the parameter by appending values, that is exactly where the contradiction gets assembled by accident. ## Saying who you mean: the two hints A silent request is much more useful when it names the user it is about, and two parameters do that — with quite different force: - **`login_hint`** *suggests* an identifier. It is a hint about which account the request concerns, useful for pre-filling or for steering an account chooser. It asserts nothing. - **`id_token_hint`** *asserts* a previously authenticated user by carrying an ID token the provider itself issued earlier. It is the natural companion to `prompt=none`: "if this particular user is still authenticated here, answer; otherwise error." One trap is worth naming explicitly, because the parameter name is reused: `id_token_hint` also appears on a **logout** request at the `end_session_endpoint`, where its job is to identify the session being ended rather than to assert who a silent authentication request is about. Same spelling, different endpoint, different purpose. ## The loop this creates when it is handled wrongly The classic production defect is a relying party that treats `login_required` as a fault and reacts by starting the flow again. The provider answers with the same error, the client retries, and the browser bounces between two sites until something gives up. The mechanism is always the same: **an expected outcome was routed into an error handler that retries**. A correct handler distinguishes three cases: 1. **Success** — a response came back; continue. 2. **An expected error** (`login_required`, `interaction_required`, `consent_required`, `account_selection_required`) — the quiet answer was no. Either stop and show the user a sign-in affordance, or send exactly one visible request without `prompt=none`. Never an automatic silent retry. 3. **Anything else** — a genuine protocol or transport failure; log it and stop. The second rule that keeps this healthy is to **cap the attempt**: one silent check per navigation, tracked by the relying party, so that no failure mode can turn into an unbounded redirect chain.
- What do `login_hint` and `id_token_hint` each add to an authentication request?`login_hint` suggests an identifier for the account the request concerns — a hint only. `id_token_hint` carries a previously issued ID token and asserts which user was already authenticated, which pairs naturally with `prompt=none`. The same parameter name on a logout request at the `end_session_endpoint` does a different job: identifying the session to end.
- Why does a badly handled silent check turn into a redirect loop?Because `login_required` is an expected answer and the client treats it as a transient fault. It retries the same silent request, the provider returns the same error, and the browser bounces between the two sites. The fixes are to route expected errors away from the retry path and to cap silent attempts at one per navigation.
- Can `prompt=none` be combined with `prompt=login` when a client wants either behaviour?No. A request that carries `none` alongside any other `prompt` value is an error, because it forbids and demands an interface in the same breath. A client that wants both behaviours makes two requests: the silent check first, and a visible one only after the silent one answers no.
saying these in an interview costs you the question
- Treats login_required as a fatal error and retries immediately
- Expects the error as an HTTP status from the authorization endpoint
- Thinks prompt=none forces the provider to create a session
- Combines none with login to cover both cases
- Believes id_token_hint means the same thing on every endpoint
- Assumes a silent request bypasses consent that was never granted