In short

On 19 July 2024 CrowdStrike pushed a Rapid Response Content update, Channel File 291, to its Falcon sensor, and Windows hosts that received it crashed and could not boot normally. The new content matched on a 21st input field that the sensor code never supplied: the template definition declared 21 fields, the code passed 20, tests had used wildcards for the 21st, and the content validator checked against the definition rather than the code. Kernel code without a bounds check read past the array, and the update went to every online sensor at once, with no staged rollout. The lesson is that content which changes what privileged code does needs the same validation, testing and staged release as code.

  • This was an outage, not a breach: CrowdStrike says the out-of-bounds read 'is not an arbitrary memory write issue', and an independent review agreed.
  • The bad content was live from 04:09 to 05:27 UTC; hosts that had already crashed could not download the fix, so many needed hands-on recovery.
  • Validate content against the interface of the code that will run it, not against the producer's description of that interface.
  • Test every field with a non-wildcard value: wildcard-only tests passed for months while the 21st field was never read.
  • Stage content like code: canary, rings with bake time, automatic halt and rollback, and customer control over timing.
  • Microsoft estimated 8.5 million affected Windows devices; that figure is Microsoft's, not part of CrowdStrike's root cause analysis.

Incident at a glance

Date
Category
Outage
Organizations
  • CrowdStrike (Falcon sensor for Windows)
  • Microsoft (Windows)
Impact
A Rapid Response Content update made Windows hosts running Falcon sensor 7.11 or later crash, many in a boot loop. Microsoft estimated 8.5 million devices were affected; many needed manual recovery.
How it was found
Hosts crashed within minutes of receiving Channel File 291; CrowdStrike reverted the content 78 minutes after release.

Timeline

  1. Sensor 7.11 ships an IPC Template Type whose definition declares 21 inputs while the code supplies 20.
  2. 04:09 UTC: Channel File 291 with a non-wildcard 21st-field criterion reaches online Windows sensors, which crash.
  3. 05:27 UTC: CrowdStrike reverts the content; crashed hosts need manual recovery.
  4. Microsoft estimates 8.5 million affected Windows devices.
  5. CrowdStrike publishes its preliminary Post Incident Review.
  6. Bounds checking is added to the Content Interpreter.
  7. A compile-time check of Template Type input counts goes into production.
  8. CrowdStrike publishes the external root cause analysis.

Verify it

  1. List every kind of content your software interprets in privileged code (rules, signatures, channel or config files, models, feature flags) and confirm each goes through a staged rollout with a halt, not a global push.
  2. For each content type, check that CI validates it against the consuming code's real interface, built from that code, and fails on any field index the code does not supply.
  3. Confirm your test suite exercises every content field with a non-wildcard value at least once.
  4. Fuzz the parser or interpreter that reads content, with sanitizers on, and keep runtime bounds checks in release builds.
  5. Rehearse recovery for a host that crashes at boot: how it gets the fixed content, who needs recovery keys, and how long a thousand machines take.
Applies to
  • CrowdStrike Falcon sensor for Windows Sensor 7.11 and later with Channel File 291 as delivered from 04:09 to 05:27 UTC on 19 July 2024
  • Any agent or service that interprets remotely delivered content Rules, signatures, configuration and model updates pushed outside the code release process

Teams that ship content, rules, signatures or configuration that privileged code interprets, such as security agents, endpoint software, WAF and detection rules, and device firmware, to fleets they do not control.

Part of
Workflow: Build an AppSec program. Collection: case studies
Learning goals and prerequisitesAbout 28 minutes: 10 to read and 18 for the exercise

What you will learn

  • Explain how a 21-versus-20 field mismatch passed validation and testing and crashed Windows hosts.
  • Validate content against the consuming code's real interface and require non-wildcard test coverage for every field.
  • Design a staged rollout and a rollback path for content updates, including hosts that cannot boot.
  • Separate CrowdStrike's findings from third-party estimates in the public record.

Before you start

Engineers who build agents, endpoint and security software, and the release and SRE teams that ship rules, signatures and configuration to fleets

  • Know the difference between a code release and a configuration or content update in your product.
  • Know what an out-of-bounds read is and why it is fatal in kernel code.
  • For the code: Python 3 for the content check, and a C compiler (Clang or GCC) for the bounds-check example.

Refresh first: Staged rollout and rollback for security-critical updates

Go to the guided practice

How a 21st field reached code that supplied 20

CrowdStrikeCustomer hostDetectionengineeringContent ValidatorContent deliveryWindows sensor(kernel)Template Instancematching field 212Checked against a21-fielddefinition2Passed2Channel File 291 toall sensors at once3Reads input 21 of20; system crash4Reverted file at 05:27UTC5Trust boundaryUntrusted input1Step, described below
  1. Ship the template typeSensor 7.11 (February 2024) adds an IPC Template Type. Its definition file declares 21 input fields; the sensor code that calls the interpreter passes 20.
  2. Validate against the definitionOn 19 July 2024 a new Template Instance matches on the 21st field. The Content Validator checks it against the 21-field definition and passes it.
  3. Push to every sensorChannel File 291 goes to all online Windows sensors at 04:09 UTC, with no canary or rings.
  4. Read past the arrayAt the next named-pipe notification, the Content Interpreter in the kernel driver reads input index 20 from a 20-entry array and Windows stops with a page fault.
  5. Revert, then recover by handCrowdStrike reverts the file at 05:27 UTC; hosts stuck in a crash loop need the file deleted from recovery mode or a snapshot restored.
Each check compared the content with a description of the code, not with the code. A staged rollout would have limited the crash to a canary ring.

A content update, not a code update, crashed Windows

CrowdStrike's Falcon sensor runs a kernel driver on Windows. Its behavior is shaped by two kinds of content: Sensor Content, compiled into each sensor release, and Rapid Response Content, which CrowdStrike pushes from the cloud in channel files to detect new attacker techniques 'without requiring sensor code changes'. On Friday 19 July 2024 at 04:09 UTC it released a Rapid Response Content update, a new version of Channel File 291. Windows hosts with sensor 7.11 or later that were online and received it crashed, and some crashed again on restart before they could fetch a fix.

CrowdStrike reverted the content at 05:27 UTC, 78 minutes later. That did not help machines already stuck in a crash loop, because they could not stay up long enough to download the fix; they needed someone to delete the file from recovery mode or restore a snapshot. Microsoft estimated that 8.5 million Windows devices were affected. This was an availability failure. CrowdStrike's technical details post says it 'is not the result of or related to a cyberattack', and its root cause analysis (RCA) says the out-of-bounds read 'is not an arbitrary memory write issue and has been independently reviewed'.

This page follows CrowdStrike's 6 August 2024 RCA and its remediation guidance. It pairs with the guide to staged rollout and rollback for security-critical updates (/domains/supply-chain/releases/staged-rollout-rollback/).

Timeline

Timeline
WhenEventSource
February 2024Sensor 7.11 introduces an IPC Template Type for named pipes and other interprocess communication; its definition declares 21 inputs, but the sensor code supplies 20.CrowdStrike RCA
Before 19 July 2024Stress tests and the first IPC Template Instances in the field all use a wildcard for the 21st field, so nothing reads it.CrowdStrike RCA
2024-07-19 04:09 UTCTwo new IPC Template Instances ship in Channel File 291; one uses a non-wildcard criterion for the 21st field. Windows hosts crash.CrowdStrike remediation hub; RCA
2024-07-19 05:27 UTCCrowdStrike reverts the content.CrowdStrike remediation hub
2024-07-20Microsoft estimates 8.5 million affected Windows devices and describes its recovery help.Microsoft
2024-07-24CrowdStrike publishes its preliminary Post Incident Review.CrowdStrike remediation hub
2024-07-25A bounds check and an input-array size check are added to the Content Interpreter.CrowdStrike RCA
2024-07-27A Sensor Content Compiler check that validates each Template Type's input count goes into production.CrowdStrike RCA
2024-08-06CrowdStrike publishes the external technical RCA, with hotfixes for sensors 7.11 and later due by 9 August and validator checks by 19 August.CrowdStrike RCA

Configuration data that drives kernel code

The RCA describes the moving parts. Template Types are compiled into the sensor and define what data a kind of detection can look at. A Template Type Definitions file says how many inputs each type uses. Detection engineers write Template Instances, regular-expression matching criteria for a type, which are bundled into Rapid Response Content and delivered as channel files. A Content Validator checks channel files against the definitions file, and a Content Interpreter in the sensor's C++ code evaluates them.

CrowdStrike stresses that 'Rapid Response Content is configuration data; it is not code or a kernel driver.' That is true of the file and beside the point for release engineering. The content decided which array index kernel code would read, so a bad file could crash the machine as surely as a bad driver. Sensor releases went through an internal test gauntlet and Microsoft's Windows Hardware Quality Labs certification, which tested them with the channel files current at the time; content shipped afterward relied on the Content Validator and CrowdStrike's own tests, and it was not staged.

Treat anything that changes what privileged code does as code for release purposes: rules, signatures, channel and configuration files, feature flags and models. It needs tests against the real consumer, a canary, rings and a rollback path. The faster path for urgent content should be faster staging, not no staging.

How 21 declared fields met 20 supplied inputs

The IPC Template Type 'defined 21 input parameter fields, but the integration code that invoked the Content Interpreter with Channel File 291's Template Instances supplied only 20 input values.' The mismatch survived sensor release testing, stress testing and several earlier content deployments 'in part' because every test and every earlier Template Instance used a wildcard for the 21st field. A wildcard matches without reading the value, so the missing input was never touched.

Three checks each compared the content with a description of the code instead of the code. The Content Validator 'based its assessment on the expectation that the IPC Template Type would be provided with 21 inputs', the RCA's 'logic error'. The automated tests used a static set of 12 cases with a wildcard in the 21st field for all Template Instances. And nothing at compile time compared the definitions file's 21 with the code's 20.

On 19 July one new Template Instance put a real criterion in the 21st field. At the next named-pipe notification, the Content Interpreter tried to read input index 20 of a 20-pointer array. The crash dump in the RCA, annotated by CrowdStrike with illustrative symbol names, shows the read in csagent!TemplateGetString with index 0x14: a page fault in kernel mode, which Windows cannot recover from. There was no runtime bounds check, so data the driver did not control decided whether it read valid memory.

Why every sensor got it at once

Finding 6 of the RCA is one line: 'Each Template Instance should be deployed in a staged rollout.' On 19 July new content went to every online sensor, and customers had no control over when Rapid Response Content arrived. Because affected hosts crashed at the next named-pipe notification, a canary ring would most likely have shown the failure within minutes, before the content reached the wider fleet.

CrowdStrike's changes are a template for any content pipeline: Template Instances now pass canary testing and are 'successively promoted to wider deployment rings or rolled back if problems are detected', with bake-in time and telemetry at each ring; customers 'can choose where and when Rapid Response Content updates are deployed'; and content updates come with release notes. The draft of SSDF 1.2 (NIST SP 800-218 Rev. 1, initial public draft, December 2025) adds a practice for exactly this, PS.4 'Ensure Software Updates Are Robust and Reliable', with tasks for tiered rollouts such as canaries and staged roll-out (PS.4.2) and robust rollback (PS.4.3). It is still a draft.

Recovery when the host cannot boot

Rollback at the source fixed every machine that had not yet crashed. For the rest, CrowdStrike's guidance was to reboot on a wired network in case the host fetched the reverted file before the crash; otherwise to boot into recovery and delete the channel files matching C-00000291*.sys, or, for cloud and virtual machines, attach the OS disk to another server and delete them there, or roll back to a snapshot from before 04:09 UTC. A channel file timestamped 05:27 UTC or later is the good version.

Encrypted disks made this slower: CrowdStrike notes that BitLocker-encrypted hosts may need a recovery key. The design lesson for anyone shipping updates is that rollback has to work when the update has broken the machine's ability to receive the next one: last-known-good content the agent falls back to after repeated failed boots, A/B partitions, or a boot counter that disables a content channel. The embedded update guide (/domains/appsec/platform-security/embedded-update-security/) covers the device version of this.

Check content against the code that will run it

The check below compares three things the incident shows can drift apart: the field list a template type declares, the number of inputs the consuming code supplies, and the fields the content and the tests actually exercise. It fails if the counts differ, if any instance or test matches on a field index the code does not supply, and if the tests never use a non-wildcard value for some field. Its tests reproduce the 21-versus-20 case; they ran with Python 3.14. Generate inputs_supplied from the consuming code at build time, not by hand, or the check only compares two descriptions again.

Testcheck_content.pyPython
"""Check a content file against the interface of the code that will run it.

The template type declares its fields; the consumer (the code that evaluates
the content) declares how many input values it actually supplies. A template
instance may only match on fields the consumer supplies, and the test suite
must exercise every field with a non-wildcard value at least once.
"""
import json
import sys

WILDCARD = "*"


def check(template_type, consumer, instances, test_instances):
    problems = []
    declared = len(template_type["fields"])
    supplied = consumer["inputs_supplied"]
    if declared != supplied:
        problems.append(
            f"{template_type['name']}: definition declares {declared} fields, "
            f"consumer supplies {supplied}"
        )
    for inst in instances + test_instances:
        for index, criterion in enumerate(inst["criteria"]):
            if criterion != WILDCARD and index >= supplied:
                problems.append(
                    f"{inst['id']}: field {index + 1} is matched but only {supplied} inputs exist"
                )
    tested = {
        i for inst in test_instances for i, c in enumerate(inst["criteria"]) if c != WILDCARD
    }
    for index in range(declared):
        if index not in tested:
            problems.append(f"tests never use a non-wildcard value for field {index + 1}")
    return problems


if __name__ == "__main__":
    with open(sys.argv[1], encoding="utf-8") as f:
        bundle = json.load(f)
    found = check(bundle["template_type"], bundle["consumer"], bundle["instances"], bundle["tests"])
    print("\n".join(found) or "OK")
    sys.exit(1 if found else 0)

Keep a bounds check where content picks the index

Validation upstream reduces bad content; it does not make the interpreter safe. Where data from a file chooses an array index in privileged code, check the index against the array's real length every time and fail closed. The function below is illustrative, not CrowdStrike's code; it compiled cleanly with Clang using -Wall -Wextra -fsanitize=address,undefined, and the test call for the 21st field returns NULL instead of reading past the array. Fuzz the interpreter with sanitizers on as well (/domains/appsec/testing/parser-fuzzing/), and see the C and C++ memory-safety guide (/domains/appsec/platform-security/memory-safety-c-cpp/).

Fixedbounds.cC
#include <stddef.h>
#include <stdio.h>

struct input { const char *buf; size_t len; };

/* Return input `index`, or NULL when the content asks for a field the caller
   did not supply. Illustrative only: not CrowdStrike's code. */
const struct input *get_input(const struct input *inputs, size_t count, size_t index) {
    if (inputs == NULL || index >= count) return NULL;
    return &inputs[index];
}

int main(void) {
    struct input inputs[20] = {{"a", 1}};
    const struct input *in = get_input(inputs, 20, 20); /* the 21st field */
    puts(in == NULL ? "rejected out-of-range field 21" : "BUG: read past the array");
    return in == NULL ? 0 : 1;
}

Which controls would have stopped or limited it?

Most of these are CrowdStrike's own remediations from the RCA. SSDF 1.1 (NIST SP 800-218, February 2022) has no practice for staged delivery; the PS.4 entries refer to the SSDF 1.2 initial public draft and may change.

Which controls would have stopped or limited it?
ControlSSDF practice or standardWould it have helped?Guide
Canary and ring deployment for content, with bake time and automatic halt and rollbackSSDF 1.2 draft PS.4.2, PS.4.3Yes: the crash would have stopped at the canary ring./domains/supply-chain/releases/staged-rollout-rollback/
Validate content in CI against the consuming code's real interface (input count generated from the code)SSDF PO.4.1, PW.8.2Yes: it would have failed the 21-versus-20 mismatch before release./domains/supply-chain/releases/staged-rollout-rollback/
Test every field with a non-wildcard value; test each new content instance, not only the firstSSDF PW.8.2Yes: the RCA names wildcard-only tests as part of why it was missed./frameworks/ssdf-product-lifecycle/
Runtime bounds checks in the interpreter, and fuzzing with sanitizersSSDF PW.5.1, PW.8.2Yes: a bounds check turns the bad content into a rejected rule, not a kernel crash./domains/appsec/platform-security/memory-safety-c-cpp/
A last-known-good fallback that works when the host cannot boot or reach the networkSSDF 1.2 draft PS.4.3Limits impact: fewer machines need hands-on recovery./domains/appsec/platform-security/embedded-update-security/
Customer control over content rollout timing and ringsSSDF 1.2 draft PS.4 (practice statement), PS.4.2Limits impact: customers could hold critical systems back a ring./domains/supply-chain/releases/trusted-publishing-and-updates/
Root-cause analysis applied to the whole class: every Template Type checked for the same mismatchSSDF RV.3.3, RV.3.4Prevents recurrence; CrowdStrike's compiler check verified no other Template Type had the problem./domains/appsec/vulnerability-response/product-incident-response/

Lessons that still apply

  • If a file changes what privileged code does, release it like code: canary, rings, bake time, automatic halt and rollback.
  • Validate content against the consuming code itself, generated from that code, not against a separate description that can drift.
  • Wildcards and defaults in tests hide unused paths. Exercise every field with a real value.
  • Keep bounds checks in the interpreter even when upstream validation exists; validation is a filter, not a guarantee.
  • Design rollback for the worst case: a host that crashes before it can fetch the fix.
  • Give customers control over when updates reach their critical systems, and tell them what changed.

What the public evidence does not establish

The RCA gives no count of affected devices; the widely cited 8.5 million is Microsoft's estimate from 20 July 2024. Financial losses reported in the press come from third-party estimates and are not part of the primary record. The RCA explains what the Content Validator checked but not why the definitions file and the sensor code disagreed on the input count in the first place, beyond the absence of a compile-time check. It does not say how many hosts recovered by downloading the reverted file before crashing again versus by manual repair. CrowdStrike's planned dates in the RCA (hotfixes by 9 August, validator checks by 19 August 2024) are commitments as of 6 August 2024; this page does not verify their completion.

Guided practice

You own the release pipeline for detection rules that an endpoint agent's kernel component interprets. A rule update is ready. Decide what the pipeline should do at each step. Treat the facts as true.

Supplied scenario material
Plain text
Rule type 'proc-tree' definition: 9 fields. Agent code for proc-tree (built from the release branch): supplies 8 inputs.
New rule R-1042 matches on field 9 with a real pattern; all existing rules use '*' for field 9.
Test suite: 40 cases, all with '*' in field 9.
Rollout plan: push to all 2 million agents at once; customers cannot defer rule updates.
Recovery: agents keep no last-known-good copy of rule files; disks are encrypted and recovery keys sit in a central vault.
  1. 1. Run the content check

    What does a check like the one on this page report for R-1042 and the test suite?

    Expected result and reasoning

    Three failures: the definition declares 9 fields but the code supplies 8; R-1042 matches on field 9, which the code does not supply; and the tests never use a non-wildcard value for field 9. The release stops.

  2. 2. Find the real fix

    Should you fix the rule, the definition or the code?

    Expected result and reasoning

    Decide which is intended. If field 9 is meant to exist, fix the code to supply it and ship that as a code release first; until it is deployed everywhere, the validator must reject rules that use field 9. Add a compile-time check that the definition and the code agree.

  3. 3. Replace the rollout plan

    Write the rollout for the next rule update.

    Expected result and reasoning

    Internal canary, then a small external ring, then wider rings, each with a bake time and health signals such as crash and boot-loop rates and agent heartbeats; automatic halt and rollback on regression; customers can place critical systems in a late ring.

  4. 4. Plan recovery

    What has to exist before an update can break boot?

    Expected result and reasoning

    A last-known-good rule set the agent falls back to after repeated failed boots, a boot counter or safe mode that disables the rule channel, a tested process for bulk recovery, and recovery keys reachable when the main systems are down.

Your deliverable: A one-page release checklist for rule updates covering validation against the code, test coverage per field, rollout rings and halt criteria, and recovery.

The fixture is a simplified model of a content pipeline. Real ring sizes, bake times and health thresholds depend on fleet size and how quickly failures show; set them from your own telemetry.

Save a draft on this device to resume later. Automatic saving begins after you choose Save. Drafts are never sent by this application; use synthetic data.

No draft saved on this device yet.

Sources & further reading

The standards, specifications and documentation behind the guidance above. Each is the evidence for a claim on this page; consult it for detail beyond the defaults and versions listed here.

  1. CrowdStrike: External Technical Root Cause Analysis, Channel File 291. 6 August 2024.
  2. CrowdStrike: Remediation and guidance hub, Channel File 291 incident (includes the preliminary Post Incident Review). PIR section updated 24 July 2024.
  3. CrowdStrike: Technical details, Falcon content update for Windows hosts. 20 July 2024.
  4. Microsoft: Helping our customers through the CrowdStrike outage. 20 July 2024.
  5. NIST SP 800-218 Rev. 1 (initial public draft): SSDF version 1.2, practice PS.4. Initial public draft, December 2025.
  6. NIST SP 800-218: Secure Software Development Framework version 1.1. Version 1.1 (February 2022).
  7. MITRE CWE-125: Out-of-bounds Read

Reference information

Download this guide as Markdown