OCPP BootNotification Message: Fields, Statuses & Fixes

The OCPP BootNotification message explained: every field in 1.6 and 2.0.1, what Accepted/Pending/Rejected mean, and the failure modes that cause outages.

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:

  1. Power on, or recover from a network outage, or be reset.
  2. 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.
  3. Send BootNotification as the first message on the new WebSocket.
  4. Wait for the response: Accepted, Pending, or Rejected.
  5. If Accepted, begin normal operation. Start heartbeating, send StatusNotification for each connector, become available for sessions.
  6. If Pending, keep waiting and re-send BootNotification at the indicated interval.
  7. 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, or Rejected.

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:

  1. 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.
  2. Alert on Pending and Rejected statuses. A charger sitting in Pending for hours is a provisioning failure that needs a human.
  3. Log the reason field on 2.0.1. Use it for diagnostic correlation. Watchdog-heavy chargers are firmware-unstable; PowerUp-heavy chargers are power-supply-unstable.
  4. Time-sync your CSMS rigorously. NTP everywhere, monitor drift, alert above one second.
  5. Standardize firmware-version strings with your hardware OEMs so your CSMS matching rules stay predictable.
  6. 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 chargePointVendor and chargePointModel are required in 1.6. Everything else is optional but useful for inventory.
  • The response’s interval means heartbeat cadence when Accepted and retry delay when Pending or Rejected. Same field, two jobs.
  • currentTime synchronizes the charger’s clock, so a wrong CSMS time silently corrupts every downstream timestamp.
  • In 2.0.1, identification moves under a chargingStation object and the reason enum 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.

Quick check

Q1. Which two fields are required in an OCPP 1.6 BootNotification payload?
Q2. What should a charger do immediately after receiving an Accepted BootNotification response?
Q3. A charger reports Accepted, Heartbeats flow, but no sessions ever start. Which is a plausible cause?
Q4. Why is the currentTime field in the response operationally important?
Q5. What does a Pending status typically indicate?

Frequently asked questions

What happens if a charger sends BootNotification but the CSMS responds with Rejected?

The charger does not start operating. It will retry BootNotification at the interval the CSMS specified, which can range from 60 seconds to 24 hours depending on the configuration. Until accepted, the charger does not accept user sessions.

Does BootNotification only fire at power-on?

Mostly. A charger sends BootNotification when it boots, after a Reset command, when its WebSocket reconnects after a long outage, or when it has been forced to re-register via configuration. It is the first message of a new session of connectivity.

What is the difference between BootNotification in OCPP 1.6 and 2.0.1?

The fields are similar but organized differently. OCPP 2.0.1 puts charge-point identification under a chargingStation object, adds a reason for the boot (PowerUp, Triggered, RemoteReset and others), and ties more cleanly into the device model.

Why does my BootNotification keep failing with Pending status?

Pending usually means the CSMS recognizes the charger but is still provisioning it, for example downloading config or applying initial settings. The charger should keep retrying at the indicated interval. If it stays Pending indefinitely, check your CSMS provisioning pipeline.

Found this useful? Share it.