OCPP LocalAuthList: Offline Charger Operation

How LocalAuthList lets a charger authorize users when the back-end is unreachable. The patterns that work and the trade-offs that come with them.

OCPP chargers normally depend on the CSMS for user authorization. When you tap your RFID card, the charger sends an Authorize message to the CSMS, the CSMS checks (often querying the user’s eMSP via OCPI), and responds with Accepted or Invalid.

But what if the charger can’t reach the CSMS? Cellular outages, ISP problems, and CSMS maintenance windows all happen, and they happen more often than anyone plans for. Without local authorization, the charger is a very expensive bollard for the duration.

LocalAuthList is the solution. It’s a list of authorized user identifiers stored on the charger itself, allowing the charger to authorize users locally when the back-end is unreachable.

This article explains how LocalAuthList works, the patterns for keeping it useful, and the trade-offs of relying on it.

The basic concept

A LocalAuthList is a list of (idTag, status, expiry) entries stored locally on the charger.

When a user presents an idTag (RFID, etc.) and the charger sends Authorize to the CSMS:

  • If the CSMS responds, the charger uses that response (CSMS is authoritative).
  • If the CSMS doesn’t respond (offline), the charger checks its local list.
    • If the idTag is in the list with status Accepted, authorize.
    • If status Blocked or Expired, reject.
    • If not in the list, behavior depends on AllowOfflineTxForUnknownId setting.

The list is pushed to the charger by the CSMS via OCPP messages.

OCPP 1.6: GetLocalListVersion, SendLocalList

Two main messages.

GetLocalListVersion. The CSMS asks the charger which version of the list it currently has:

The charger responds:

{ "listVersion": 42 }

SendLocalList. The CSMS sends a new list or updates to the existing list:

{
  "listVersion": 43,
  "localAuthorizationList": [
    { "idTag": "ABC123", "idTagInfo": { "status": "Accepted" } },
    { "idTag": "DEF456", "idTagInfo": { "status": "Blocked" } },
    { "idTag": "GHI789", "idTagInfo": { "status": "Accepted", "expiryDate": "2027-01-01T00:00:00Z" } }
  ],
  "updateType": "Full"
}

The updateType is either:

  • Full. Replace the entire list with this one.
  • Differential. Apply these as changes to the existing list.

OCPP 2.0.1: GetLocalListVersionRequest, SendLocalListRequest

Same conceptual structure, slightly different naming and richer data:

{
  "versionNumber": 43,
  "localAuthorizationList": [
    {
      "idToken": { "idToken": "ABC123", "type": "ISO14443" },
      "idTokenInfo": { "status": "Accepted", "cacheExpiryDateTime": "2027-01-01T00:00:00Z" }
    }
  ],
  "updateType": "Full"
}

The idToken structure in 2.0.1 supports more identifier types (ISO15118 EmaIds, central tokens, key codes, etc.). This mirrors the broader shift in OCPP 2.0.1, where flat 1.6 fields become structured objects.

The Authorize fallback flow

Without LocalAuthList:

  1. User presents idTag.
  2. Charger sends Authorize to CSMS.
  3. CSMS unreachable; Authorize times out.
  4. Charger has no way to know if user is valid.
  5. Charger rejects (or accepts based on AllowOfflineTxForUnknownId setting).

With LocalAuthList:

  1. User presents idTag.
  2. Charger either checks the local list first or sends Authorize to the CSMS first, depending on the firmware.
  3. If CSMS responds, use that response.
  4. If CSMS unreachable and idTag is in local list with Accepted status, authorize.
  5. If CSMS unreachable and idTag is NOT in local list, reject (or accept based on AllowOfflineTxForUnknownId).

The LocalAuthList becomes the authoritative source during offline periods.

flowchart TD
    A[User presents idTag] --> B{CSMS reachable?}
    B -->|Yes| C[Use CSMS response]
    B -->|No| D{idTag in<br/>local list?}
    D -->|Accepted| E[Authorize offline]
    D -->|Blocked or Expired| F[Reject]
    D -->|Not found| G{AllowOffline<br/>for unknown?}
    G -->|True| E
    G -->|False| F
    style E fill:#e8f5e9,stroke:#2e7d32
    style F fill:#ffebee,stroke:#c62828

Configuration variables that matter

A few OCPP configuration variables affect LocalAuthList behavior.

LocalAuthListEnabled. Turns LocalAuthList on or off on the charger. If false, the list is ignored even if present.

LocalAuthListMaxLength. The maximum number of entries the charger supports. Reported by the charger; read-only from the CSMS’s perspective.

SendLocalListMaxLength. The maximum number of entries that can be sent in a single SendLocalList message. The CSMS must batch large updates.

AllowOfflineTxForUnknownId. If true, the charger authorizes any idTag when CSMS is unreachable (even unknown ones), with the assumption that the CSMS will reconcile later. If false, only known idTags from LocalAuthList work offline.

AuthorizationCacheEnabled. A related but distinct feature. The authorization cache stores idTags that recently authorized via CSMS query, so a re-presentation doesn’t require a new query. Useful supplement to LocalAuthList. The distinction between RFID tokens and contract-based Plug & Charge auth (coming soon) matters here, because LocalAuthList covers the former only.

The size constraint

Charger memory is finite, and the ceiling differs by model. Do not guess it: the charger reports its own limit in LocalAuthListMaxLength, and SendLocalListMaxLength separately caps how many entries fit in a single update message, so a large list has to be batched.

Once your user base exceeds what a charger can hold, you have to choose what goes on it. Strategies:

Push only active users. Maintain “last seen” data per user; push only the most-recent N thousand.

Push only frequent users at each location. If charger X is at a workplace, push the employees of that workplace, not the entire network.

Push only highest-priority partners. If your eMSP partner A is your largest, push their users; rely on online lookup for smaller partners.

Tiered approach. Top-tier users in LocalAuthList; others fall back to AllowOfflineTxForUnknownId.

The right strategy depends on your operational model. Workplace chargers can be highly selective; public DC fast chargers serving anonymous travelers need broader coverage or AllowOffline.

Update frequency

How often to push the LocalAuthList to chargers.

Daily. Common pattern. Captures user additions, removals, status changes within 24 hours. Reasonable balance of freshness and bandwidth.

Real-time on changes. Push differential updates as users change. Lower latency but more message traffic. Useful for chargers with bandwidth budget.

Weekly. Acceptable for stable user bases. Users added today won’t work at chargers until next weekly push.

Hourly. Aggressive but achievable. Catches changes faster but uses more bandwidth.

A common pattern: nightly full sync plus real-time differential pushes for important changes (new partner, mass user import, etc.).

When to use LocalAuthList

It’s not always the right answer. Considerations.

Use LocalAuthList when:

  • Network reliability matters for the charger’s location.
  • Cellular signal is weak or unreliable.
  • You have a defined user base that fits in charger memory.
  • Downtime tolerance is low.

Maybe skip LocalAuthList when:

  • Charger has reliable wired internet.
  • User base is too large to push meaningfully.
  • AllowOfflineTxForUnknownId is sufficient (you’ll reconcile billing later).

Definitely use it for:

  • Workplace chargers with known employee base.
  • Apartment chargers with known resident base.
  • Fleet depots (coming soon) with known vehicle list.

Less critical for:

  • Highway DC fast chargers with reliable wired internet and broad public user base.

The reconciliation problem

LocalAuthList authorizations happen offline. The CSMS doesn’t know about them in real time. Reconciliation matters.

When the charger reconnects after an offline period:

  1. The charger reports buffered events (StartTransaction, MeterValues, StopTransaction) to the CSMS.
  2. The CSMS sees transactions for users it didn’t pre-authorize.
  3. The CSMS handles billing, querying the eMSP for the real authorization status covering the time of the session.
  4. If the user was actually invalid (revoked, expired, blocked) at the time, the CSMS must decide: write off the loss, attempt to bill anyway, dispute with the eMSP.

This reconciliation is the cost of offline operation. LocalAuthList minimizes this by encoding what was known at last push time, but doesn’t eliminate it.

Common implementation pitfalls

A list of things that go wrong.

LocalAuthList not updated. Charger has stale list. Newly-added user can’t charge; recently-blocked user still can. Periodic sync verification matters.

LocalAuthListMaxLength exceeded. CSMS tries to push 10,000 entries to a charger that only supports 5,000. Either the SendLocalList fails or the charger truncates silently. Validate before sending.

Version mismatch. CSMS thinks the charger has version 42; charger actually has version 40 (a recent update was lost). Differential updates applied to wrong base. Always verify with GetLocalListVersion before differential updates.

AllowOfflineTxForUnknownId set wrong. True when you wanted false (or vice versa) leads to unexpected auth behavior during outages.

Cache vs LocalAuthList confusion. The auth cache is separate from LocalAuthList. They interact. Understand the distinction in your specific charger’s implementation.

Charger reports support but doesn’t actually implement. Some chargers claim LocalAuthList support but ignore the list. Test with offline scenarios.

Operational best practices

A short checklist.

  1. Push the LocalAuthList on a schedule that matches your operational reality.
  2. Validate updates by querying GetLocalListVersion after pushing.
  3. Monitor per-charger list freshness in your operations dashboard.
  4. Test offline scenarios during commissioning. Simulate the network failure and verify the authorization behaviour you expect, rather than discovering it during a real outage.
  5. Reconcile afterwards. Review offline-authorized transactions after every outage and identify any that should have been rejected.
  6. Define AllowOfflineTxForUnknownId policy per charger location and document it.

The honest summary

LocalAuthList is essential for chargers that operate in environments with unreliable connectivity. Its design is straightforward; the operational discipline around keeping it current, sized appropriately, and reconciling offline transactions is where the work happens. Get this layer right and your chargers stay useful during the inevitable network outages; ignore it and you’re vulnerable to every CSMS or cellular hiccup.

Quick check

Q1. In OCPP 1.6, which message does the CSMS use to ask a charger which list version it currently holds?
Q2. What is the difference between a Full and a Differential updateType in SendLocalList?
Q3. A charger reports LocalAuthListMaxLength of 5,000 but your network has 100,000 users. What is a valid strategy?
Q4. Why does the reconciliation problem exist with offline authorizations?
Q5. Which OCPP 2.0.1 field carries the identifier in a SendLocalListRequest entry?

Frequently asked questions

What happens if a charger loses internet?

Without LocalAuthList, the charger cannot authorize anyone by itself, because every authorization decision belongs to the CSMS. With LocalAuthList, the charger holds a local copy of allowed identifiers and can authorize from that copy even when the CSMS is unreachable.

How big can a LocalAuthList be?

OCPP does not mandate a size. Each charger reports its own ceiling in the LocalAuthListMaxLength configuration variable, so read that rather than assuming a number. Whatever it is, a large network cannot fit its whole user base on a charger, which is why LocalAuthList is designed for a scoped subset rather than a mirror of your database.

Does LocalAuthList work with Plug & Charge?

Indirectly. PnC authentication uses ISO 15118 contract certificates and the charger validates these locally already. LocalAuthList is for RFID and similar identifier-based authorization. Both are forms of local authorization but use different mechanisms.

How often should the LocalAuthList be updated?

Frequency follows from how fast your user base changes and how much offline resilience you need. The question to ask is how stale a list you can tolerate during an outage, because that staleness is exactly the window in which a revoked card still works. A daily push is a reasonable default for a network with routine churn; a fixed private fleet can go much longer.

Found this useful? Share it.