IEC 61850 Report Control Blocks: BRCB and URCB Explained

By | August 3, 2026

A data set says what an IED can send. A report control block says when, why, how much detail, and to whom. Every reporting problem in a substation — missing events after a comms drop, a client that never receives anything, reports flooding the station bus during a fault — traces back to an RCB attribute somebody set wrong or wrote in the wrong order.

This guide covers both control block types, every attribute that matters, the two packed lists that do the real work, and the write sequence that silently fails if you get it backwards.

Buffered or unbuffered: the only decision that matters first

There are two flavors, and choosing between them is not a style preference.

A URCB (unbuffered report control block) sends reports on a best-efforts basis. If no association exists, or the transport simply isn’t fast enough to keep up, events are lost. Fine for a live HMI display where only the present state matters.

A BRCB (buffered report control block) buffers internal events so that values aren’t lost to transport flow control or a dropped connection, then delivers them when the client returns. The standard is explicit about what this is for: the BRCB provides the sequence-of-events functionality. Use it for anything where a missed event is unacceptable — SOE, disturbance analysis, historians, alarm lists.

Worth noting that flow control, not just connection loss, is in scope. A BRCB protects you from a client that’s merely slow, which on a busy station bus happens more often than an outright disconnection.

The obvious question: why not always buffer? Because buffers are finite. A BRCB whose client stays away long enough overflows, drops the oldest entries, and tells you it happened via a flag in the next report. Buffering converts “data lost silently” into “data lost visibly,” which is a real improvement, not a guarantee.

One constraint surprises people, and it’s normative: a server restricts access to a report control block instance to one client at a time. That client exclusively owns the instance and receives its reports; once reserved, no other client can even set its attributes. Multiple clients wanting the same values need multiple instances of the control block, which is why IEDs ship with several — and why a client that can’t enable reporting is often just finding every instance already claimed by someone else’s SCADA.

How many instances exist is a local implementation issue, reflected in the IED’s SCL. There’s no protocol answer to “how many should there be”; you read it from the configuration file.

The attributes

Both control blocks share most of their structure. Here is what lives inside, with the BRCB-only and URCB-only members marked.

AttributePurposeWritable while enabled?
RptIDIdentifier carried in every report. If NULL, the report carries the control block’s own object reference insteadNo
RptEnaThe on switchYes — it’s the switch
DatSetReference to the data set being reportedNo
ConfRevConfiguration revision counter of the data setRead only
OptFldsPacked list: which optional fields appear in reportsNo
BufTmBuffer time in milliseconds — coalesces a burst into one reportNo
SqNumSequence number of reports sentRead only
TrgOpsTrigger conditions: which events cause a reportNo
IntgPdIntegrity period in milliseconds; 0 means no integrity reportsNo
GIWrite TRUE to start a general interrogationYes
OwnerIdentifies the client that owns the block — optionalRead only
Resv (URCB)Client reservation flagNo
PurgeBuf (BRCB)Write TRUE to discard buffered entriesNo
EntryID (BRCB)Identifier of a buffer entry — the resume point after reconnectionNo
TimeOfEntry (BRCB)Timestamp of the last entry written to the bufferRead only
ResvTms (BRCB)Reservation time in seconds — optionalYes

Two of those need a closer look.

ResvTms exists to stop a redundant SCADA pair from stealing each other’s reporting. A positive value reserves the block dynamically and states how many seconds the reservation survives after the association is lost; zero means unreserved; −1 means the block is exclusively reserved for a configured set of clients. Where the attribute isn’t implemented at all, reservation falls back to pre-configuration or simply to whichever client first enables reporting — which is exactly the behavior older IEDs show.

Owner identifies the client currently holding the block. It’s optional too, but where a server implements it, it answers the question every commissioning engineer eventually asks out loud: who took my report control block?

The “writable while enabled” column is not documentation trivia. It’s the source of the most common integration bug in the field, covered below.

TrgOps: the five reasons a report happens

TrgOps is a packed list of five trigger conditions, all mandatory in the model. In MMS it becomes a bitstring of at least six bits, where bit 0 is reserved for backward compatibility with UCA 2.0:

BitTriggerFires when
1data-changeA value changes
2quality-changeA quality flag changes, even if the value doesn’t
3data-updateThe value is refreshed, even to the same value
4integrityThe IntgPd timer expires — full data set
5general-interrogationA client wrote GI = TRUE

Practical guidance per bit. data-change is the workhorse; almost every RCB has it. quality-change matters more than people expect — a measurement that goes questionable while reading the same number is exactly the event an operator needs, and leaving this bit off hides it. data-update is for cases where the act of refreshing carries meaning (counters, re-sampled values); enabling it casually on an analog data set is how you generate a report storm. integrity with a sensible IntgPd is the safety net that repairs any drift between the IED and the client database. general-interrogation is what a client uses at startup to pull a complete picture without waiting for changes.

A design rule that holds up: data-change plus quality-change plus integrity, with GI available on demand. Add data-update only when you can name the reason.

OptFlds: what rides along with the data

OptFlds decides which metadata fields appear in each report. The model defines eight configurable fields; the MMS mapping assigns them bit positions in a bitstring, with bit 0 reserved and a ninth position carrying segmentation in the reported copy only.

BitFieldWorth enabling?
0reserved
1sequence-numberYes — gap detection
2report-time-stampYes
3reason-for-inclusionYes — tells you which trigger fired, per value
4data-set-nameDebugging only
5data-referenceDebugging only
6buffer-overflowYes, on any BRCB
7entryIDYes, on any BRCB
8conf-revisionUseful
9segmentationReserved here — meaningful only in the reported copy

Two of these are close to mandatory on a buffered block. buffer-overflow is the only signal that data was lost during a disconnection — without it, a gap in your event list looks like a quiet period. entryID is what lets a returning client resume from where it left off rather than re-reading the entire buffer.

Two are close to harmful in production. data-set-name and data-reference attach naming strings to every report, inflating message size significantly for information the client already knows from configuration. Turn them on to troubleshoot, turn them off before commissioning ends.

BufTm and IntgPd: the two timers

BufTm is a burst absorber, expressed in milliseconds. When a trigger fires, the server waits BufTm before sending, and any further changes inside that window join the same report. Zero means one report per change — clean in theory, brutal during a fault when forty status points move in half a second. A modest BufTm turns that storm into a single message and, as a bonus, preserves the natural grouping of related changes.

IntgPd is the integrity period: every IntgPd milliseconds, provided the integrity trigger is set, the values of all members of the data set are reported regardless of activity. It exists so a client’s picture cannot drift indefinitely from the IED’s. Zero means no integrity reports at all, and an IED that doesn’t support integrity periods rejects any attempt to set a non-zero value. The tradeoff is bandwidth against staleness tolerance — seconds for small critical sets, minutes for large measurement sets.

One interaction worth knowing: BufTm has no effect on an integrity report. Integrity fires and sends; it doesn’t wait out the buffer window. Same for a general interrogation, which is a request rather than a timer — write GI = TRUE and the block starts the interrogation, then clears the attribute back to FALSE by itself. A client that writes GI and then reads it back expecting TRUE has misread the model.

Note that both are configured per control block, so different data sets on the same IED can behave completely differently. That’s the intended design: a status data set with a short BufTm and a long IntgPd, a measurement data set with no data-change trigger at all and integrity reporting only.

The write order that breaks integrations

Here is the rule that costs engineers afternoons: most RCB attributes cannot be written while RptEna is TRUE. DatSet, OptFlds, TrgOps, IntgPd, BufTm, RptID — all locked once reporting is enabled.

So the correct configuration sequence is always:

  1. Disable reporting (RptEna = FALSE)
  2. For a URCB, reserve it (Resv = TRUE)
  3. Write DatSet, then TrgOps, OptFlds, BufTm, IntgPd
  4. Enable reporting (RptEna = TRUE)

And to reconfigure, reverse it: RptEna FALSE first, then Resv FALSE. Clients that write attributes in one batch without ordering them get partial success — some writes land, others are rejected, and reporting comes up with a mixture of intended and stale settings. That failure is quiet: no alarm, just a report stream that doesn’t match what the engineering tool shows.

Two more rules with teeth. Enabling reporting fails if DatSet is NULL — a control block with no data set assigned cannot be turned on, which is the first thing to check when RptEna won’t stick.

And on a BRCB, changing the value of RptID, DatSet, BufTm, TrgOps, or IntgPd purges the buffer, exactly as if PurgeBuf had been written TRUE. Reconfiguring a buffered block throws away whatever it was holding, so do it during a maintenance window, not while chasing an event. Note the asymmetry: a write that doesn’t actually change the value doesn’t purge, and changing OptFlds is rejected outright rather than purging.

What a report actually looks like

Reports are delivered as MMS InformationReports, and the structure has one quirk worth knowing before you open a capture: the report references a named variable list called RPT that is created, reported, and deleted instantaneously. You will not find a persistent object by that name on the IED. It exists for the duration of one message.

The contents arrive as an ordered sequence: RptID first, then the reported OptFlds, then each optional field that OptFlds enabled — sequence number, timestamp, data set name, buffer overflow flag, EntryID, ConfRev, segmentation fields — followed by the inclusion bitstring, then optionally the data references, then the values, then optionally the reason codes.

The inclusion bitstring is the piece that makes reports readable. It has one bit per member of the data set, in data set order, and a set bit means that member’s value is present in this report. That’s how a report carrying three changed values out of a sixty-member data set stays small: fifty-seven bits of zero instead of fifty-seven values. When analyzing a capture, read the inclusion bitstring first — it tells you which points the report is about before you decode a single value.

The reason codes, if enabled, are one bitstring per included value, using the same bit layout as TrgOps. So a value included because of a general interrogation carries bit 5, one included because of a quality change carries bit 2. Per-value causality, in the report itself.

Since 61850 reporting rides on MMS, all of this decodes with Wireshark’s MMS dissector — the same technique as any MMS traffic, described in the Wireshark for IEC 61850 MMS guide.

Naming: reading brcb01 and urcb02

RCB instances follow a recommended naming convention that shows up in SCL files and captures alike: brcb<yy><xx> and urcb<yy><xx>, where xx is the instance number 01 through 99 (omitted on the first instance) and yy carries the functional constraint when the referenced data set contains members of a single FC.

So brcbST02 is the second buffered control block in that logical node, reporting a status data set. Vendors may use other component names as a local option, but most follow the convention, and recognizing it saves a trip to the documentation.

Mistakes that keep recurring

Client receives nothing, no error. Check RptEna actually stuck. It silently refuses if DatSet is NULL, and on a URCB it usually needs Resv set first.

Client can’t enable any RCB. Every instance is already reserved by another client. Look for indexed instances, or find out who owns the ones in use.

Events missing after a comms outage. The block is unbuffered. That’s not a fault, that’s the definition — move to a BRCB.

Gaps in the event list with no explanation. Buffer overflow occurred and the buffer-overflow OptFld isn’t enabled, so nobody was told.

Report storms during faults. BufTm is zero, or data-update is enabled on a measurement data set.

Configuration doesn’t match the engineering tool. Attributes were written while enabled and rejected. Redo the sequence with RptEna FALSE first.

Reports are far bigger than expected. data-set-name and data-reference left enabled after commissioning.

FAQ

What’s the difference between BRCB and URCB in one line?

The BRCB queues reports through a connection loss and delivers them afterward; the URCB doesn’t, and those events are lost.

Can two clients use the same report control block?

No. An RCB is claimed by the client that enables it. Multiple clients need multiple instances, which is why IEDs provide indexed RCBs.

Why won’t RptEna go TRUE?

Most often DatSet is NULL, another client holds the block, or a URCB hasn’t been reserved with Resv. All three fail quietly.

What does BufTm actually buffer?

Time, not storage. It delays sending briefly so simultaneous changes combine into one report. Buffering across connection loss is the BRCB’s queue — a different mechanism entirely.

Do I need integrity reporting if I have data-change?

Usually yes. Data-change tells you about transitions; integrity guarantees the client’s picture is periodically corrected regardless of what was missed or mis-processed. On critical data sets, run both.

What is EntryID for?

It identifies a position in a BRCB’s buffer. A reconnecting client presents the last EntryID it processed, and the server resumes from there instead of resending everything.

Are report control blocks created at runtime?

No. Instances of report control blocks are configured in the server at configuration time. Data sets can sometimes be created dynamically; the control blocks that report them cannot.

How do I find out which client is holding an RCB?

If the server implements the optional Owner attribute, read it — it identifies the current owner. Otherwise you’re down to reading ResvTms (non-zero means reserved) and asking around. Neither attribute is mandatory, so on some IEDs the honest answer is that the protocol won’t tell you.

Why does my SqNum look different between two IEDs?

The BRCB and URCB use different widths for it — the buffered block’s sequence number has the larger range. If a client treats both identically it will mishandle rollover on one of them.

Author: Zakaria El Intissar

I've spent 13 years in power system automation, electrical protection, and SCADA communication, as an automation and industrial computing engineer. ScadaProtocols.com is where I turn what I've learned on site into plain guides and working tools — so other engineers can decode, analyze, and troubleshoot industrial communication protocols without the guesswork.