# How RADIUS Works, Message by Message

Source: https://startwithidentity.com/guides/protocols/radius-message-flow/
Last updated: 2026-11-05
License: content by Start with Identity. Cite the source URL.

---

A RADIUS authentication is a short UDP conversation between a network access server (NAS), such as a VPN gateway or Wi-Fi controller, and a RADIUS server: an **Access-Request**, possibly an **Access-Challenge** and a second request, and finally an **Access-Accept** or **Access-Reject**, followed by accounting. Each packet is a fixed header plus attributes defined in [RFC 2865](https://www.rfc-editor.org/rfc/rfc2865). This page decodes each packet with fake values, ties every attribute to its section, and lists what both sides must check, with particular attention to the Blast-RADIUS lessons. For what RADIUS is and its status, see the [RADIUS standard page](https://startwithidentity.com/standards/radius/).

Addresses below are from the documentation ranges in [RFC 5737](https://www.rfc-editor.org/rfc/rfc5737). The shared secret is never sent; it only feeds the hashes.

## The sequence at a glance

| # | From → to | Packet (Code) | Spec |
| --- | --- | --- | --- |
| 1 | NAS → server (UDP 1812) | Access-Request (1) with username and password | [§4.1](https://www.rfc-editor.org/rfc/rfc2865#section-4.1) |
| 2 | Server → NAS | Access-Challenge (11) with `State` and a prompt | [§4.4](https://www.rfc-editor.org/rfc/rfc2865#section-4.4) |
| 3 | NAS → server | Access-Request (1) with the code and the same `State` | [§5.24](https://www.rfc-editor.org/rfc/rfc2865#section-5.24) |
| 4 | Server → NAS | Access-Accept (2) or Access-Reject (3) | [§4.2](https://www.rfc-editor.org/rfc/rfc2865#section-4.2), [§4.3](https://www.rfc-editor.org/rfc/rfc2865#section-4.3) |
| 5 | NAS → server (UDP 1813) | Accounting-Request (4), Start | [RFC 2866 §4.1](https://www.rfc-editor.org/rfc/rfc2866#section-4.1) |
| 6 | Server → NAS | Accounting-Response (5) | [RFC 2866 §4.2](https://www.rfc-editor.org/rfc/rfc2866#section-4.2) |

With push-based MFA, steps 2 and 3 disappear: the server holds the first request while it waits for the user to approve on their phone.

## The packet header

```
 Code (1 byte) | Identifier (1) | Length (2) | Authenticator (16) | Attributes ...
      0x01          0x2a          0x00b4      9f 3c 1e ... (random)
```

| Field | Meaning | Spec |
| --- | --- | --- |
| Code | 1 Access-Request, 2 Access-Accept, 3 Access-Reject, 11 Access-Challenge; 4 and 5 for accounting. | [§3](https://www.rfc-editor.org/rfc/rfc2865#section-3), [RFC 2866 §3](https://www.rfc-editor.org/rfc/rfc2866#section-3) |
| Identifier | Matches replies to requests; also used to detect retransmissions. | §3 |
| Length | 20 to 4096 octets. | §3 |
| Request Authenticator | In Access-Request, 16 unpredictable random octets. Also the input to the `User-Password` keystream. | §3 |
| Response Authenticator | In replies, `MD5(Code + ID + Length + RequestAuth + Attributes + Secret)`. The only built-in integrity check, and the one Blast-RADIUS forged. | §3 |
| Attributes | Type (1 byte), Length (1 byte), Value. | [§5](https://www.rfc-editor.org/rfc/rfc2865#section-5) |

## Message 1: Access-Request

```
Code 1 (Access-Request)  Identifier 42  Authenticator 0x9f3c1e7a...(16 random octets)
  80 Message-Authenticator = 0x5b0e...(HMAC-MD5 over the packet)
   1 User-Name             = "ada@example.com"
   2 User-Password         = 0x6c1a...(16 octets, hidden with the shared secret)
   4 NAS-IP-Address        = 192.0.2.10
  32 NAS-Identifier        = "vpn-gw-01"
   5 NAS-Port              = 0
  61 NAS-Port-Type         = Virtual (5)
   6 Service-Type          = Framed (2)
  31 Calling-Station-Id    = "203.0.113.45"
  30 Called-Station-Id     = "198.51.100.1"
```

| Attribute (type) | Meaning | Spec |
| --- | --- | --- |
| Message-Authenticator (80) | HMAC-MD5 over the whole packet, keyed with the shared secret. Mandatory with EAP; send it always. | [RFC 3579 §3.2](https://www.rfc-editor.org/rfc/rfc3579#section-3.2) |
| User-Name (1) | The identity being authenticated. | [§5.1](https://www.rfc-editor.org/rfc/rfc2865#section-5.1) |
| User-Password (2) | Password padded to 16-octet blocks and XORed with `MD5(secret + RequestAuthenticator)`, chained per block. Confidential only as long as the secret is. | [§5.2](https://www.rfc-editor.org/rfc/rfc2865#section-5.2) |
| CHAP-Password (3), alternative | CHAP response instead of a password; a request must not carry both. | [§5.3](https://www.rfc-editor.org/rfc/rfc2865#section-5.3), §4.1 |
| NAS-IP-Address (4) / NAS-Identifier (32) | Which NAS is asking; at least one is required. | [§5.4](https://www.rfc-editor.org/rfc/rfc2865#section-5.4), [§5.32](https://www.rfc-editor.org/rfc/rfc2865#section-5.32) |
| NAS-Port (5), NAS-Port-Type (61) | Port and its type; 5 is Virtual, used for VPN sessions. | [§5.5](https://www.rfc-editor.org/rfc/rfc2865#section-5.5), [§5.41](https://www.rfc-editor.org/rfc/rfc2865#section-5.41) |
| Service-Type (6) | Requested service, for example Framed (2) for a network session or Administrative (6) for device management. | [§5.6](https://www.rfc-editor.org/rfc/rfc2865#section-5.6) |
| Calling-Station-Id (31) | The caller's side. Defined for the phone number a call came from; in practice NAS vendors put the client IP for VPN or the MAC address for Wi-Fi here. Useful for policy and logs. | [§5.31](https://www.rfc-editor.org/rfc/rfc2865#section-5.31) |
| Called-Station-Id (30) | The called side, originally the dialed number; vendors commonly use the VPN address or the access point MAC and SSID. | [§5.30](https://www.rfc-editor.org/rfc/rfc2865#section-5.30) |

## Messages 2 and 3: Access-Challenge for a one-time code

```
Code 11 (Access-Challenge)  Identifier 42  Authenticator 0x...(Response Authenticator)
  80 Message-Authenticator = 0x...
  18 Reply-Message         = "Enter the 6-digit code from your authenticator app"
  24 State                 = 0x7f2c9a41e3b0...(opaque to the NAS)

Code 1 (Access-Request)  Identifier 43  Authenticator 0x...(new random)
  80 Message-Authenticator = 0x...
   1 User-Name             = "ada@example.com"
   2 User-Password         = 0x...(the one-time code, hidden as above)
  24 State                 = 0x7f2c9a41e3b0...(copied unchanged)
   4 NAS-IP-Address        = 192.0.2.10
```

`State` must be returned unmodified and the NAS must not interpret it ([§5.24](https://www.rfc-editor.org/rfc/rfc2865#section-5.24)); `Reply-Message` is text to display ([§5.18](https://www.rfc-editor.org/rfc/rfc2865#section-5.18)). EAP (for 802.1X) uses exactly this challenge loop, with each round's EAP packet in `EAP-Message` (79) ([RFC 3579 §3.1](https://www.rfc-editor.org/rfc/rfc3579#section-3.1)).

## Message 4: Access-Accept

```
Code 2 (Access-Accept)  Identifier 43  Authenticator 0x...(Response Authenticator)
  80 Message-Authenticator = 0x...            -- first attribute, per Blast-RADIUS guidance
  25 Class                 = "sess-8c41-example"
  27 Session-Timeout       = 28800
  11 Filter-Id             = "vpn-finance"
  26 Vendor-Specific       = (vendor 9, a group or VLAN assignment)
```

| Attribute (type) | Meaning | Spec |
| --- | --- | --- |
| Class (25) | Opaque value the NAS must echo in accounting, tying the session to this authorization. | [§5.25](https://www.rfc-editor.org/rfc/rfc2865#section-5.25) |
| Session-Timeout (27) | Maximum session length in seconds. | [§5.27](https://www.rfc-editor.org/rfc/rfc2865#section-5.27) |
| Filter-Id (11) | Name of a filter or policy the NAS applies. | [§5.11](https://www.rfc-editor.org/rfc/rfc2865#section-5.11) |
| Vendor-Specific (26) | Vendor ID plus vendor-defined sub-attributes, commonly used for roles and VLANs. | [§5.26](https://www.rfc-editor.org/rfc/rfc2865#section-5.26) |

An Access-Reject (3) may carry a `Reply-Message` and nothing that grants access.

## Messages 5 and 6: accounting

```
Code 4 (Accounting-Request)  Identifier 7
  40 Acct-Status-Type = Start (1)
  44 Acct-Session-Id  = "00000A1F"
   1 User-Name        = "ada@example.com"
  25 Class            = "sess-8c41-example"
   4 NAS-IP-Address   = 192.0.2.10
```

The server answers Accounting-Response (5). Stop records carry duration and byte counts. Accounting is how you prove which user held which address at what time ([RFC 2866 §5.1](https://www.rfc-editor.org/rfc/rfc2866#section-5.1), [§5.5](https://www.rfc-editor.org/rfc/rfc2866#section-5.5)).

## The checks each side must run

**NAS (the RADIUS client)**

1. **Identifier and source.** Accept a reply only if its Identifier matches an outstanding request and it came from the configured server address (§3).
2. **Response Authenticator** verifies with the shared secret; otherwise silently discard (§3).
3. **Require `Message-Authenticator` on every reply**, verify it, and expect it as the first attribute of Access-Accept and Access-Reject. This is the [Blast-RADIUS](https://www.blastradius.fail/) mitigation; RFC 3579 §3.2 already requires it for EAP.
4. **Return `State` unchanged** and never act on its contents (§5.24).

**RADIUS server**

5. **Known client and secret.** Silently discard packets from clients without a configured shared secret ([§2](https://www.rfc-editor.org/rfc/rfc2865#section-2)), and use a distinct secret per NAS, at least 16 octets and never empty (§3, Administrative Note).
6. **Well-formed request.** Require `NAS-IP-Address` or `NAS-Identifier`, and exactly one of `User-Password`, `CHAP-Password` or `State`, never both password types (§4.1).
7. **Require `Message-Authenticator` on requests** and drop requests without it; for EAP, RFC 3579 §3.2 says such requests SHOULD be silently discarded.
8. **Protect the transport.** Across any network you do not fully control, run RADIUS inside TLS: RadSec ([RFC 6614](https://www.rfc-editor.org/rfc/rfc6614), port 2083) or RADIUS/1.1 ([RFC 9765](https://www.rfc-editor.org/rfc/rfc9765)), which removes the MD5 constructions altogether.

## Common implementation mistakes, with the CVEs and techniques behind them

| Mistake | What goes wrong | Real examples |
| --- | --- | --- |
| PAP or CHAP without `Message-Authenticator` | An attacker in the path forges Access-Accept from Access-Reject with an MD5 collision; MFA behind RADIUS is bypassed | [CVE-2024-3596](https://startwithidentity.com/cves/cve-2024-3596/) (Blast-RADIUS) |
| `Message-Authenticator` sent but not required | Downgrade: the attacker strips it and the old attack works | Same CVE; configure "require" on both sides |
| RADIUS server management plane exposed | The network access control system itself is taken over | [CVE-2026-76460](https://startwithidentity.com/cves/cve-2026-76460/) (Cisco ISE, exploited) |
| Push MFA through RADIUS without number matching | Users approve attacker-initiated logins | [MFA fatigue and push bombing](https://startwithidentity.com/techniques/mfa-fatigue-push-bombing/) |
| RADIUS-fronted VPN with password-only users | Internet-facing guessing against the directory behind it | [Password spraying](https://startwithidentity.com/techniques/password-spraying/), [credential stuffing](https://startwithidentity.com/techniques/credential-stuffing/) |
| One shared secret for every NAS, never rotated | One compromised device decrypts every password and forges every reply | Rotate and segment secrets, then move to TLS |

## Try it locally

There is no SWI browser tool for RADIUS, which runs over UDP. FreeRADIUS's [radclient](https://freeradius.org/radiusd/man/radclient.html) sends test packets against a lab server: `radclient -x 192.0.2.20 auth example-shared-secret` reads attributes from standard input and prints the reply, and its `-b` flag enforces the Blast-RADIUS checks, requiring `Message-Authenticator` as the first attribute of every reply. If your server's replies fail with `-b`, fix the server before relying on RADIUS for MFA.

## Related

[RADIUS standard page](https://startwithidentity.com/standards/radius/), [how LDAP works, message by message](https://startwithidentity.com/guides/protocols/ldap-message-flow/), [how Kerberos works, message by message](https://startwithidentity.com/guides/protocols/kerberos-message-flow/), [how WebAuthn works, message by message](https://startwithidentity.com/guides/protocols/webauthn-message-flow/). Glossary: [RADIUS](https://startwithidentity.com/glossary/radius/), [MFA](https://startwithidentity.com/glossary/mfa/), [phishing-resistant MFA](https://startwithidentity.com/glossary/phishing-resistant-mfa/).
