skip to content

Why should a RADIUS server answer a duplicate Access-Request from a cache instead of authenticating it again?

level: seniorimportance: nice to knowfreq 30%

answer

  1. the client is repeating itself
  2. one question deserves one answer
  3. authentication is not repeatable
  4. the Authenticator separates retry from new
  5. cache must outlive the retry window

basics

~20 s

Because a duplicate is a retransmission of a request already answered, and authentication is not repeatable: a one-time credential is consumed, a challenge conversation advances twice, and back-end work doubles exactly when the server is already struggling.

solid answer

~40 s

A retransmitted `Access-Request` repeats the same `Identifier` and the same Request Authenticator from the same source address and port, which is how a server recognises it. RFC 2865 describes that detection and permits resending the previous reply; RFC 5080 recommends keeping a short-lived duplicate-detection cache for it. Re-running the authentication instead is not harmless: a one-time credential already consumed will now fail, a multi-round conversation's `State` can be advanced a second time, and the back-end lookups are repeated under exactly the load conditions that caused the loss. It also means two identical packets can yield two different answers. The cache must outlive the client's whole retransmission window, or a late retry is treated as new.

code

pseudocode · 12 lines
pseudocode
function on_access_request(packet, from_address, from_port):
    key    = (from_address, from_port, packet.Identifier)
    cached = duplicate_cache.get(key)

    if cached exists and cached.authenticator equals packet.Authenticator:
        send(cached.reply)            # same answer, no re-authentication
        return

    reply = authenticate(packet)      # new request: same key, new Authenticator
    duplicate_cache.put(key, packet.Authenticator, reply,
                        lifetime longer than the client retry window)
    send(reply)

go deeper

for a junior

The thing to remember is that a lost reply makes the client send the same request again, so a server can receive one question twice and should give back the one answer it already produced.

for a middle

Explain the detection key — client source address, source port, Identifier — and that the Request Authenticator is what separates a retransmission from a new request that happens to reuse the Identifier.

for a senior

Show the consequences you have seen: a one-time credential consumed by the first pass and refused on the retry, a challenge conversation advanced twice, and a cache lifetime shorter than the client's retry window producing intermittent, load-dependent failures.

for a principal

The general point is that an at-least-once transport forces every request handler to decide whether its work is repeatable. Authentication is not, so the deduplication window is a real design parameter that has to be reasoned about against the fleet's retry behaviour.

## What the server is actually looking at A RADIUS server sees two datagrams that are identical in every octet, from the same source address and source UDP port, a second or two apart. The first was answered; the reply was lost on the way back, so the client retransmitted. Nothing in the second packet announces itself as a retry — recognising it is entirely the server's job. ## The detection key The tuple that identifies a duplicate is: - the **client's source IP address**; - the **source UDP port** the packet came from; - the packet's **`Identifier`**; - and, as the discriminator, the **Request Authenticator**. The first three alone are not enough. The Identifier is a single octet and gets recycled quickly, so the same tuple will legitimately recur for a genuinely different request within seconds on a busy device. What separates the two cases is the Authenticator: a retransmission repeats it byte for byte, while a new request carries a new one. **Same tuple, same Authenticator: duplicate. Same tuple, different Authenticator: a new request that must be processed on its own.** ## Why re-processing is not harmless The instinct is that authenticating twice is merely wasteful. It is worse than that: 1. **One-time credentials are consumed.** If the first pass already spent the code the user typed, the second pass evaluates a credential that is no longer valid and produces an `Access-Reject`. The user is refused for an attempt that had already succeeded — and the only visible cause is a lost reply on a bad link. 2. **Multi-round conversations advance twice.** A `State` value handed out in an `Access-Challenge` usually indexes a conversation with a step counter or an attempt budget. Running the same packet through twice can move that conversation on a step the user never took, or burn an attempt. 3. **The load arrives at the worst moment.** Retransmissions cluster exactly when the link or the server is already in trouble. Re-running every lookup a second time adds work precisely where there is none to spare, making the next loss likelier. 4. **Two identical packets get two different answers.** A server whose back-end state changed between the passes can accept the first and refuse the retry. The client, by design, believes whichever reply reaches it. Resending the stored reply avoids all four, and it is also simply correct: the client asked one question, and it should get one answer however many copies of the question arrive. ## How long the cache must live The entry has to outlive the client's entire retransmission window. If the client follows RFC 5080's recommended bounds it may keep retrying for tens of seconds, so a cache that expires in a second or two will see the last retransmission as a brand-new request and authenticate it after all — the very failure the cache exists to prevent. The cache is also per-client, because the key starts with the client's address, and it is inherently bounded: 256 Identifier values per source port put a hard ceiling on how many entries any one socket can need. ## What the specifications actually say It is worth being precise about strength here, because it is easy to overclaim: - RFC 2865 describes how a server **can** detect a duplicate — same client source address, same source port, same Identifier, within a short span — and allows it to resend the previous reply. - RFC 5080 **recommends** the duplicate-detection cache as the way to do this, and supplies the retransmission model on the client side that the cache lifetime must be matched against. So this is a strong recommendation with a clear failure mode, not a bare protocol MUST, and an answer that says the specification mandates it is teaching a false certainty. ## The accounting side has the same shape The accounting exchange, on its own port, produces duplicates for the same reason: a lost `Accounting-Response` makes a client resend the record. The detection mechanism is identical, and the argument for answering from cache rather than reprocessing is if anything stronger, because a record counted twice is a corrupted measurement rather than just a wasted lookup. ## What this question is really testing That you understand retransmission as a two-sided problem. The client's half — retransmit identically — is only useful because the server's half recognises the duplicate. A candidate who has operated this will also volunteer the Authenticator as the discriminator, and will notice that a cache shorter than the client's retry window is worse than no cache at all, because it makes the failure intermittent and load-dependent.

  • What distinguishes a duplicate from a genuinely new request carrying the same Identifier?
    The Request Authenticator. A retransmission repeats the whole packet byte for byte, including that field; a new request carries a new one. Since the Identifier is one octet and recycles quickly, the Authenticator is the only reliable discriminator, and a cache keyed without it will answer a new request with a stale reply.
  • How long should an entry stay in the duplicate-detection cache?
    Longer than the client's whole retransmission window — tens of seconds under RFC 5080's recommended bounds. A shorter lifetime lets the final retry through as a new request and re-runs the authentication, which is the exact failure the cache exists to prevent, and it shows up only under the load that causes retries.
  • What does the user actually experience when a server re-authenticates a duplicate?
    An unexplained refusal. The first pass succeeded and consumed the one-time code; the retransmission evaluates a credential that is now spent and produces an Access-Reject. The user sees a wrong-code error for a code that was right, and it only happens when the link is dropping packets.

saying these in an interview costs you the question

  • Thinks a repeated Identifier always means a fresh login attempt.
  • Says re-authenticating a duplicate is harmless because authentication is idempotent.
  • Keys the duplicate cache on the Identifier alone.
  • Assumes the second reply may legitimately differ from the first.
  • Sets a cache lifetime shorter than the client's retry window.
  • Claims the specification flatly mandates caching the reply.