Browser Negotiate sign-on works for an archive's registered host name but prompts on an alternative name — why?
answer
- the URL's host becomes the target name
- a different string, a different principal
- the realm answers that it knows no such service
- the negotiation narrows instead of failing
- the only symptom is a password box
basics
~20 sThe client builds the service principal name from the host in the URL, as HTTP/<host>. An alternative name is a different principal; with none registered the KDC answers KDC_ERR_S_PRINCIPAL_UNKNOWN (7) and the negotiation drops to a weaker mechanism or a prompt.
solid answer
~40 sA client targeting HTTP `Negotiate` derives its target from the **host component of the URL**, as a service principal name of the form `HTTP/<host>` (a name of type `NT-SRV-HST (3)`). It then asks the realm for a service ticket for exactly that string. An alternative host name is a different string and therefore a different principal: if none is registered, the KDC answers `KDC_ERR_S_PRINCIPAL_UNKNOWN (7)`, the Kerberos mechanism can produce no context token, and SPNEGO moves on to the next entry in `mechTypes` — the legacy NTLM challenge-response mechanism — or, failing that, to whatever else the service offers. Nothing in the HTTP exchange announces that Kerberos failed; the visible symptom is a password box and a slower sign-in.
code
pseudocode · 13 lineshost = host component of the request URL # "rushes.internal.example"
target = "HTTP/" + lowercase(host) # an NT-SRV-HST service principal name
reply = request a service ticket for target
if reply is KDC_ERR_S_PRINCIPAL_UNKNOWN (7)
remove the Kerberos V5 mechanism from mechTypes
if mechTypes still has an entry
continue the negotiation with the next mechanism
else
surface the acceptor's remaining challenge to the user
else
build AP-REQ from the ticket and send it as the mechTokengo deeper
Remember that the name in the address bar is what the client asks for a ticket for, so two names for one service are two different things to the protocol.
Explain the derivation of HTTP/<host>, what the realm answers when no such principal exists, and why the negotiation continues instead of failing.
Diagnose the silent case: same status code, same user report, several causes, and the evidence you need lives in the advertised and selected mechanisms rather than in the HTTP response.
Decide whether a silent fallback is acceptable at all in your estate, and own the register of names a service answers on, since every unregistered one is a permanent quiet downgrade.
## The name the client uses is the name you typed When a journalist in an outside-broadcast truck opens the newsroom archive, the client does not consult a catalogue to find out what the service is called. It takes the **host component of the URL** and constructs a service principal name from it: `HTTP/<host>`, a name of type `NT-SRV-HST (3)`, with the host part normally lower-cased and the service part conventionally upper case. The port is not part of the name in this form. That derivation is the entire mechanism, and it explains the whole class of failure: the protocol's target is a **string derived from what the user typed**, not a canonical identity of the machine. So `HTTP/archive.internal.example` and `HTTP/rushes.internal.example` are two different principals. Registering one in the realm does nothing for the other. ## What happens when no such principal exists 1. The client derives `HTTP/<host>` from the URL. 2. It asks the realm's ticket-granting service for a service ticket for that name. 3. The KDC finds no principal by that name and answers **`KDC_ERR_S_PRINCIPAL_UNKNOWN (7)`**. 4. The Kerberos mechanism can now produce nothing, so it is dropped from the negotiation. 5. SPNEGO continues with the next entry in `mechTypes` — in practice the legacy **NTLM** challenge-response mechanism. 6. If that is unavailable or refused, the client falls back to whatever other authentication the service offers, and the user sees a prompt. The important property of that sequence is that **it is all legitimate protocol behaviour**. SPNEGO's job is to find a mechanism both ends support. Losing the strongest one is a narrowing, not an error, and there is no field anywhere in the HTTP exchange that says "Kerberos was attempted and failed". ## Why the symptom is so misleading | What the user reports | What it could be | |---|---| | "It asks me for a password now" | no principal registered for the name in the URL | | "It asks me for a password now" | the client was never able to obtain a ticket at all | | "It asks me for a password now" | the acceptor no longer offers the negotiation | | "It is slower than it was" | extra legs from a fallback mechanism | All four produce the same user-visible outcome, and the HTTP status line is `401` in every case. The distinguishing evidence is inside the tokens: which mechanisms the initiator advertised, and which one the acceptor selected. ## Working the problem - **Compare strings, not machines.** Put the exact host from the URL beside the service principals registered for the service. Equality of the *string* is what matters. - **Check every name clients actually use.** A service reached by more than one name needs a registered principal for each name that will be typed, because each one produces a different target. - **Establish whether Kerberos was even attempted.** A context token that begins with the negotiation wrapper and lists the Kerberos mechanism tells you the client tried; one that offers only the legacy mechanism tells you the client never intended to. - **Do not assume the realm rewrote the name.** Whether a KDC is asked to canonicalise a name at all is a realm-side decision, not something the client does silently on the user's behalf. - **Separate this from a credential problem.** A missing service principal is not a problem with the user's sign-in; re-acquiring a ticket-granting ticket changes nothing. ## What is actually lost in the fallback The fallback is not merely slower. With Kerberos, the client presents a ticket it cannot read, sealed under the service principal's long-term key, and — when it requested mutual authentication — can conclude from the acceptor's final token that the service held that key. The legacy challenge-response mechanism instead proves knowledge of a password-derived key through an exchange of challenges, and gives the client no comparable assurance about the service it is talking to. A deployment that silently accepts the fallback has changed what its sign-on proves, without changing anything anybody decided. ## The design consequence Because the target name is derived from the URL, the set of names that work is a deliberate list, not an emergent property. Every additional name a service answers on — a shorter one for people to type, one per site, one that survives a move — is another principal somebody must register, and the cost of forgetting one is not an outage but a quiet, permanent downgrade for whoever uses that name.
- Why does the user see a prompt rather than an error?Because falling back is a legitimate outcome of a negotiation, not a fault. SPNEGO exists to find a mechanism both ends support, so losing the strongest entry narrows the list and the exchange carries on. The HTTP layer reports `401` either way, and no field carries the reason the Kerberos mechanism dropped out.
- What is actually lost when the exchange lands on the legacy challenge-response mechanism?The proof changes shape. Instead of presenting a ticket sealed under the service principal's long-term key, the client answers a challenge with a password-derived key, and it gains no comparable assurance that the service holds the key it claims to. The sign-on still works, and it proves less.
- One archive service answers on several host names. What does the protocol need?A registered service principal for every name clients will actually use, because the target is derived from the URL rather than from a canonical record of the host. Whether those names share one key or hold separate ones is a realm-side decision; what the protocol requires is that each name resolves to a principal the KDC knows.
saying these in an interview costs you the question
- Says the client targets the resolved address, not the name
- Thinks the realm canonicalises every alternative name automatically
- Assumes a failed ticket request surfaces as an HTTP error
- Believes the fallback mechanism gives equivalent assurance
- Thinks the port number forms part of the service principal name
- Blames the user's credentials for a missing service principal