802.11 Association State Machine
Three states. Every frame class that's allowed in each. Click any transition or state to see the exact frames, what can go wrong, and the Wireshark filter to find it.
— Shankar K. · Source: IEEE 802.11-2020, Clause 11.3 + CWNA-109 Study Guide
Unassociated
Unassociated
Associated
| Step | Frame | Direction | State change | Wireshark filter |
|---|---|---|---|---|
| 1 | Probe Request (optional) | Client → Any AP | Stays in State 1 | wlan.fc.type_subtype == 0x04 |
| 2 | Probe Response | AP → Client | Stays in State 1 | wlan.fc.type_subtype == 0x05 |
| 3 | Authentication Request | Client → AP | Stays in State 1 | wlan.fc.type_subtype == 0x0b |
| 4 | Authentication Response (status 0) | AP → Client | State 1 → State 2 | wlan.fc.type_subtype == 0x0b |
| 5 | Association Request | Client → AP | Stays in State 2 | wlan.fc.type_subtype == 0x00 |
| 6 | Association Response (status 0) | AP → Client | State 2 → State 3 | wlan.fc.type_subtype == 0x01 |
| 7 | EAPOL M1 (if WPA2/WPA3) | AP → Client | Stays in State 3 | eapol |
| 8 | EAPOL M2, M3, M4 | Client ↔ AP | Stays in State 3 | eapol |
| 9 | Encrypted data frames | Client ↔ AP | State 3 (data flowing) | wlan.fc.protected == 1 |
| — | Deauthentication (any time) | AP or Client → other | → State 1 (any state) | wlan.fc.type_subtype == 0x0c |
| — | Disassociation (from State 3) | AP or Client → other | State 3 → State 2 | wlan.fc.type_subtype == 0x0a |
| — | Reassociation Request (roaming) | Client → New AP | Stays in State 2 | wlan.fc.type_subtype == 0x02 |
| — | Reassociation Response (status 0) | New AP → Client | State 2 → State 3 | wlan.fc.type_subtype == 0x03 |
Wi-Fi icon shows "Connected. No Internet." for several seconds, then flips green and everything works. Repeats every 20 minutes. User thinks the router is broken.
The client passes Probe, Authentication, and Association in under 100 milliseconds — the 802.11 state machine completed to State 3 successfully. Then it stalls on DHCP for several seconds waiting for an IP address. During those seconds the radio layer is healthy but no IP routing exists, which the OS reports as "connected but no internet."
Knowing the state machine reached State 3 (not earlier) points away from the radio. A capture confirms: 802.11 Association Response succeeded with status 0, then DHCP DISCOVER broadcasts from the client go unanswered for seconds before OFFER arrives. The problem is upstream — DHCP server, DHCP relay, or VLAN path — not the radio.
Modern operating systems auto-retry the full state machine silently. A struggling laptop cycles through it 3-5 times per minute, filling logs with duplicate transitions. When reviewing, filter to a single client MAC and a 60-second window — the actual failure pattern becomes obvious.
The Wi-Fi state machine isn't a single connection event — it's three doors your device walks through, in order. State 1 (Unauthenticated, Unassociated) is where every device starts. It can hear Beacons and send Probes, but that's it. State 2 (Authenticated, Unassociated) means the device has exchanged authentication frames with the AP — formally, they've shaken hands. State 3 (Authenticated, Associated) is the destination: the AP has assigned an AID (Association ID) and real data frames can flow.
The reason this three-door model matters for troubleshooting: when Wi-Fi "isn't working," the device is almost always stuck at one of the doors. Password looks right but nothing happens? Failed at State 1 → 2. Icon says connected but nothing loads? Made it to State 3 but DHCP stalled. Kicked off every few seconds? Something pushed it back from State 3 to State 1 with a Deauth frame.
Every state has a defined set of frames it's allowed to send and receive (Class 1, 2, 3 above). Sending a data frame from State 1 is an error — the AP responds with a Deauth and reason code 7. That discipline is what makes the state machine diagnostic-friendly: every failure has a specific signature.
Each state transition has a specific frame pair: Auth Req/Resp for State 1→2, AssocReq/AssocResp for State 2→3, ReassocReq/ReassocResp for roaming between APs. Each response carries a status code in the fixed parameter field — 0 means success, anything else is a rejection with a specific meaning.
AssocReq → AssocResp (status=17) — AP at capacity, stayed in State 2
AssocReq → AssocResp (status=23) — cipher mismatch, handshake aborted
AssocReq → (no response) → Deauth — driver or policy issue
Deauthentication versus Disassociation is a common source of confusion. Deauth sends the client all the way back to State 1, requiring full re-authentication. Disassoc sends it to State 2 — authentication is preserved, re-association is fast. AP sends Deauth reason 4 on inactivity timeout (IoT device went quiet); Disassoc reason 8 means "leaving BSS gracefully." Which one the AP sends tells you whether it kicked the client hard or soft.
PMKSA caching (IEEE 802.11-2020 clause 12.6.10.2) changes the picture on return visits. After the first full authentication, the AP caches the PMK with a PMKID for several minutes to hours. On return, the client supplies the PMKID in its (Re)AssocReq — if it matches a cached entry, the AP skips full 802.1X/SAE and goes straight to the 4-way handshake. That's why re-connecting to a previously-joined AP is typically sub-second: a PMKSA cache hit short-circuits the slow parts.
802.11r Fast Transition extends the state machine. A client that completed FT initial mobility domain association holds a PMK-R0 (derived during initial 802.1X). When roaming, it computes PMK-R1 for the target AP from R0 plus the R1 and R0 key-holder identities plus BSSID. The ReassocReq carries an FT IE with R1KH-ID, R0KH-ID, SNonce, and MIC — the target AP validates the MIC using R1 and, if good, responds with ReassocResp (status 0) containing ANonce and GTK. No 4-way handshake runs on the roam. Failure signature: ReassocResp status 53 ("Invalid PMKID") means R0 or R1 key distribution broke between the two APs in the mobility domain, usually a missed update in the controller's fast-roaming configuration.
Protected Management Frames (PMF, 802.11w) changes State 3 behavior. Without PMF, management frames in State 3 (Deauth, Disassoc, Action) are unprotected and forgeable — the basis of the deauth flood attack. With PMF required (RSN Capabilities MFPC=1, MFPR=1), these frames carry a MIC computed with the IGTK (Integrity Group Temporal Key for broadcast management) or PTK-derived MIC key for unicast. A forged Deauth fails MIC verification at the client and is silently dropped — but the client sends an SA Query to the AP to verify the association is still valid. SA Query exchange is observable as Action frames, category 8. Rapid SA Query exchanges in a capture indicate a deauth attack is being attempted.
Wi-Fi 7 MLO complicates "State 3." An MLD (Multi-Link Device) doesn't have one state machine — it has one per affiliated STA, but they share a single MLD-level association. A two-link MLD can transition its 5 GHz affiliated STA from State 3 to State 1 (channel switch, DFS event, or block-ack reset) while the 6 GHz STA remains in State 3. The client is still associated at the MLD level. In captures you'll see per-link Deauth frames and ML Reconfiguration elements that reconcile state. Legacy state-machine tools that assume one-BSSID-one-state lose track.
Class 3 enforcement edge case (IEEE 802.11-2020 clause 11.3.3). An AP receiving Class 2 from a State-1 client responds with Deauth reason 6; Class 3 from a State-1 client gets Deauth reason 7; Class 3 from a State-2 client gets Disassoc reason 7. These are deterministic — reliable fingerprints for detecting a client (malicious or buggy driver) trying to skip states.
Sticky-client diagnosis via the state machine. A client that refuses to roam despite poor RSSI shows up as: maintained State 3 on AP-A with ever-declining signal, no ReassocReq to AP-B, eventually Deauth from AP-A on frame retry exhaustion. The state machine itself is healthy — the roaming decision logic on the client is broken. 802.11k Neighbor Reports and 802.11v BSS Transition Management (BTM) are the tools to nudge these clients; their behavior is visible in Action frames category 10 (WNM), action code 7 (BTM Request).
Wireshark — state transition forensics. wlan.fc.type_subtype == 0x0b && wlan_mgt.fixed.status_code != 0 for failed auth,
wlan.fc.type_subtype == 0x01 && wlan_mgt.fixed.status_code != 0 for failed assoc,
wlan.fixed.category_code == 8 for SA Query (PMF probing),
wlan.fixed.category_code == 10 for WNM / BTM.
Building WiFi Analyser V2 · CWNA-109 in progress · one post every two weeks