The BootNotification message is the first thing a charge point says after it establishes a WebSocket connection to its CSMS (Charging Station Management System). It is how the charger identifies itself, how the CSMS confirms it is a known device, and how the two sides agree on the heartbeat interval that follows. If you are new to the protocol overall, what is OCPP covers the bigger picture, and OCPI vs OCPP vs ISO 15118 explains where OCPP sits relative to the roaming and vehicle-to-charger protocols.
It is a tiny message, five or six fields and a simple request/response, but it is the gateway to everything else. A broken BootNotification means a charger that never comes online, never accepts users, and sits stubbornly “offline” in your operations dashboard even when the hardware is fine.
This article walks through exactly what BootNotification carries in both OCPP 1.6 and 2.0.1, what each response status means, and the failure modes behind the most common real-world support tickets.
The basic flow
A charger goes through this sequence:
- Power on, or recover from a network outage, or be reset.
- Establish WebSocket connection to the CSMS URL it has configured. This involves a TCP handshake, a TLS handshake in modern deployments, and the WebSocket upgrade.
- Send BootNotification as the first message on the new WebSocket.
- Wait for the response: Accepted, Pending, or Rejected.
- If Accepted, begin normal operation. Start heartbeating, send StatusNotification for each connector, become available for sessions.
- If Pending, keep waiting and re-send BootNotification at the indicated interval.
- If Rejected, stay in registration-failed mode and re-send at the indicated interval.
The whole exchange takes milliseconds when everything is healthy.
stateDiagram-v2
[*] --> Connecting
Connecting --> BootSent: WebSocket up
BootSent --> Accepted: status Accepted
BootSent --> Pending: status Pending
BootSent --> Rejected: status Rejected
Pending --> BootSent: retry
Rejected --> BootSent: retry
Accepted --> Operating: heartbeat<br/>and status
Operating --> [*]
What BootNotification carries (OCPP 1.6)
A 1.6 BootNotification payload:
{
"chargePointVendor": "ExampleCo",
"chargePointModel": "X1-Outdoor-22kW",
"chargePointSerialNumber": "EX-2024-098765",
"chargeBoxSerialNumber": "EX-CB-2024-098765",
"firmwareVersion": "1.4.7-prod",
"iccid": "8931086224231234567",
"imsi": "204041234567890",
"meterType": "ExampleMeter-22A",
"meterSerialNumber": "EM-2024-554433"
}
The fields:
- chargePointVendor (required). The manufacturer name, as a free-text string the OEM chooses. CSMSes routinely key allow-list rules and firmware-matching logic off this value, which is why an OEM changing its capitalization between firmware builds can take a fleet offline.
- chargePointModel (required). The specific model.
- chargePointSerialNumber. Serial of the charge point itself.
- chargeBoxSerialNumber. Serial of the controller board or charge box, often identical to the above.
- firmwareVersion. Current firmware string. The format is OEM-defined; some use semver, some use date stamps.
- iccid and imsi. SIM card identifiers, for cellular-connected chargers.
- meterType. The energy meter installed inside.
- meterSerialNumber. That meter’s serial.
Only vendor and model are required by the spec. Everything else is optional, though OEMs commonly send most fields and CSMSes commonly use them for inventory tracking.
What the CSMS responds with
The response carries the registration decision:
{
"currentTime": "2026-06-26T08:00:00.000Z",
"interval": 300,
"status": "Accepted"
}
- currentTime. Server time in UTC. The charger uses this to sync its clock, which matters because every subsequent message timestamp derives from it.
- interval. How often, in seconds, the charger should send Heartbeat messages. Typical configured values run 60 to 300 seconds for accepted chargers, longer for pending, longer still for rejected.
- status.
Accepted,Pending, orRejected.
If status is Pending or Rejected, the interval tells the charger how long to wait before retrying BootNotification. Same field, different meaning, and misreading it is a classic implementation bug.
What BootNotification carries (OCPP 2.0.1)
OCPP 2.0.1 reorganizes the same information under a chargingStation object and adds context about why the boot happened. For the broader set of changes between releases, see the OCPP version comparison.
{
"chargingStation": {
"model": "X1-Outdoor-22kW",
"vendorName": "ExampleCo",
"serialNumber": "EX-2024-098765",
"firmwareVersion": "1.4.7-prod",
"modem": {
"iccid": "8931086224231234567",
"imsi": "204041234567890"
}
},
"reason": "PowerUp"
}
The reason enum tells the CSMS why this BootNotification fired. Possible values:
- PowerUp. First boot after power was applied.
- Triggered. Sent in response to a TriggerMessage (coming soon) command from the CSMS.
- RemoteReset. After a CSMS-initiated reset.
- LocalReset. After a local reset, from a button press or watchdog.
- FirmwareUpdate. After a firmware update was applied.
- ApplicationReset. Software-level restart without a hardware reset.
- ScheduledReset. Planned reset on a schedule.
- Watchdog. A watchdog timer fired.
- Unknown. The charger does not know why.
This context is genuinely useful operationally. A charger that boots with PowerUp once a day is probably losing power overnight, which points at a circuit problem rather than a protocol one. A charger that boots with Watchdog repeatedly has a firmware stability problem.
The three response statuses, in depth
Accepted
The charger is recognized and authorized, and can begin normal operation. The response includes the heartbeat interval and current time.
What the charger does next:
- Sets its internal clock to currentTime.
- Starts sending Heartbeat at the specified interval.
- Sends StatusNotification for each connector: Available, Faulted, and so on.
- If a vehicle is already plugged in, because the charger rebooted mid-session, sends StatusNotification reflecting that state.
- Waits for user interaction or CSMS commands.
Pending
The CSMS recognizes the charger but is not ready to accept it. Typical reasons:
- The charger was just provisioned and the CSMS is still applying initial configuration.
- The CSMS is in maintenance mode for this charger.
- The CSMS is waiting for an operator action, such as approving a newly-registered charger.
The charger keeps retrying at the indicated interval. On any retry the CSMS may transition the status to Accepted once provisioning finishes, or to Rejected if an operator declines it.
Rejected
The CSMS does not recognize the charger, or is refusing to accept it. Reasons:
- The charger’s identity, meaning vendor, model, or serial, does not match any expected record.
- The charger is registered against a different CSMS URL.
- The charger has been administratively deactivated.
- The charger’s certificate failed validation, in mutual-TLS configurations.
The charger waits at the indicated interval and retries. It does not begin normal operation. Users can plug in, but nothing happens, because the charger has no authorization to start sessions.
This is the failure mode most likely to bite during a hardware swap or a site relocation. A charger pre-provisioned against the wrong CSMS record will loop on Rejected indefinitely. The hardware looks perfect on site, the LEDs are normal, and the entire fault lives in the registration handshake. If you are staring at one right now, the BootNotification rejection walkthrough reproduces each cause live and shows the frames.
Common failure modes
Things that go wrong with BootNotification, roughly in order of how often you meet them.
WebSocket never connects
The most common failure is not BootNotification itself. It is the WebSocket that BootNotification is supposed to flow over. Causes:
- Wrong CSMS URL in the charger’s config.
- DNS resolution failure. The charger cannot resolve the CSMS hostname, because of a firewall, a captive portal, or broken DNS.
- TLS certificate validation failure. The charger’s trust store does not include the CSMS’s CA, or the CSMS presents a certificate the charger will not accept.
- Cellular outage. The SIM has no signal, or the carrier is blocking the destination.
- Authentication header missing. Where the CSMS enforces a security profile, the credential is checked during the WebSocket upgrade. Missing or wrong credentials get the connection rejected before BootNotification is ever sent.
Diagnosing this means looking at the charger’s local logs, often over a serial console, or the CSMS’s connection-attempt logs. Stepping through a healthy boot in the OCPP simulator first is a cheap way to know exactly which frame you should be seeing and are not.
Status stuck Pending forever
The charger keeps retrying and never gets Accepted. Causes:
- CSMS provisioning pipeline broken. The workflow that should transition Pending to Accepted is failing silently.
- Operator approval outstanding. Someone needs to approve the charger in the CSMS UI and has not.
- Partial identity. The charger is recognized but missing fields the CSMS requires before it will accept.
Charger gets Accepted but never sees user sessions
BootNotification succeeded and Heartbeats are flowing, but no sessions ever start. Causes:
- StatusNotification missing. The CSMS thinks all connectors are Faulted or unknown. Check whether StatusNotification with status Available was sent after boot.
- Tariff missing. Some CSMSes refuse sessions on chargers with no configured tariff. This is a provisioning gap, not a protocol fault.
- Local lockout. The charger has a local out-of-service control engaged.
- Roaming wiring incomplete. Authorize requests are rejected because the CSMS does not know how to validate them.
Clock drift
The currentTime in the response is what the charger uses to sync its clock. If the CSMS sends the wrong time, because the server is misconfigured or NTP is broken, the charger’s clock is wrong and every subsequent timestamp is wrong with it: meter readings, transaction events, everything. This is nasty precisely because nothing fails visibly. Your dashboard simply shows charging sessions happening at the wrong time, and by the time anyone notices, the billing data is already wrong.
Verify CSMS time sync deliberately. UTC, NTP, no drift.
Firmware version mismatch
The charger reports firmware version “1.4.7-prod” but your CSMS expects “1.4.7” without the suffix, so the CSMS rejects the boot on an unknown version. Annoying, and fixable by relaxing the matching rules.
Operational best practices
If you operate a CPO, a few things are worth doing deliberately:
- Monitor BootNotification frequency per charger. A charger that boots more than once a day is a warning sign. Repeated boots mean connectivity instability, watchdog resets, or a power problem worth investigating.
- Alert on Pending and Rejected statuses. A charger sitting in Pending for hours is a provisioning failure that needs a human.
- Log the
reasonfield on 2.0.1. Use it for diagnostic correlation. Watchdog-heavy chargers are firmware-unstable; PowerUp-heavy chargers are power-supply-unstable. - Time-sync your CSMS rigorously. NTP everywhere, monitor drift, alert above one second.
- Standardize firmware-version strings with your hardware OEMs so your CSMS matching rules stay predictable.
- Test reboots. Trigger a Reset during maintenance windows and confirm BootNotification flows cleanly. You want to find these bugs before your users do.
What BootNotification doesn’t tell you
A few things it does not cover, despite seeming like it should:
- Per-connector state. That arrives via StatusNotification after boot completes.
- Active transactions. A charger that rebooted mid-session reports the in-flight transaction through separate post-boot messages, such as TransactionEventRequest with eventType Updated in 2.0.1.
- Configuration values. The CSMS knows what it pushed, and the charger does not echo it back at boot. To verify, use GetConfiguration in 1.6 or GetVariables in 2.0.1 after boot.
- Capability discovery beyond model. Knowing the model tells the CSMS roughly what to expect, but discovering which optional OCPP features the firmware actually supports takes further messages.
Key takeaways
BootNotification is a small, simple message that everything else depends on. A few things worth holding onto:
- It is the first message on every new WebSocket, and nothing else works until it returns
Accepted. - Only
chargePointVendorandchargePointModelare required in 1.6. Everything else is optional but useful for inventory. - The response’s
intervalmeans heartbeat cadence when Accepted and retry delay when Pending or Rejected. Same field, two jobs. currentTimesynchronizes the charger’s clock, so a wrong CSMS time silently corrupts every downstream timestamp.- In 2.0.1, identification moves under a
chargingStationobject and thereasonenum turns each boot into a diagnostic signal.
Almost every OCPP support ticket that begins “the charger is offline” or “the charger will not accept sessions” resolves into a question about whether BootNotification succeeded. The message is trivial to implement and easy to under-instrument, and the gap between those two facts is where the support cost lives.
For what happens next in the connectivity lifecycle, see Heartbeat and the connection lifecycle and the StatusNotification deep dive.