Metrological CBOR (Tag 44252)
Status: Stable. This document is the normative specification of CBOR tag 44252 and serves as the semantics reference of its IANA registration.
Version: 1.0 (2026-08-18)
The numeric identifications of Section 4 became permanent with the IANA registration of tag 44252, recorded on 2026-08-19. Changing one of them is from now on a change to a registered format rather than an editorial matter.
Point of contact: Achim Friedland <achim.friedland@graphdefined.com>, GraphDefined GmbH
Implementations:
- Vanaheimr Styx CBOR C# (Apache License 2.0)
- Metrological CBOR Type Script (Apache License 2.0)
Worked example: tag-44252-signed-example.md carries two metrological values through three signature layers of a charging transaction, byte by byte.
Text format and JSON: metrological-text.md specifies the one-string text form of a metrological value and the document-level conversion between CBOR and JSON built on it.
Test vectors: test-vectors/ is the machine-readable conformance annex — golden encodings, must-reject inputs, text renderings and the JSON conversion — exercised continuously against both reference implementations by the cross-implementation conformance suite.
1. Introduction
The Concise Binary Object Representation (CBOR, [RFC 8949]) has no standardized tag for readings of physical quantities. Encoding such readings as plain numbers loses three properties that matter in metrology, and especially in legal metrology (calibration law):
- The unit of measure. A bare
230is meaningless without "volt". - The exact decimal representation as displayed by the instrument.
A reading of
1.10 kWhcarries more information than1.1 kWh: the trailing zero states the resolution of the measurement. Binary floating-point numbers can represent neither the value0.1exactly nor a decimal scale at all. - The measurement uncertainty. A value without a statement of uncertainty is, strictly speaking, not a measurement result.
Tag 44252 addresses all three while remaining readable by generic CBOR decoders: without knowledge of the tag, a decoder still sees a well-formed array of standard CBOR numbers.
2. Notation
The data structure is described in CDDL ([RFC 8610]). Byte sequences are written as uppercase hexadecimal.
3. The tag
metrological-value = #6.44252([
value : number, ; the reading
unit : unit-ref, ; named unit or product of powers
? prefix : int, ; SI prefix as a power of ten
? uncertainty : number / uncertainty-map
])
number = int / bignum / decfrac
bignum = #6.2(bstr) / #6.3(bstr) ; RFC 8949, Section 3.4.3
decfrac = #6.4([exponent: int, mantissa: int / bignum]) ; RFC 8949, Section 3.4.4
unit-ref = named-unit / [+ unit-factor]
named-unit = uint / tstr ; registry id or unit symbol
unit-factor = [named-unit, exponent]
exponent = int / [numerator: int, denominator: uint] ; rational, e.g. [-1, 2] for √
uncertainty-map = {
1 => number, ; magnitude, as reported
? 2 => number, ; coverage factor k (default 1)
? 3 => number, ; coverage probability, ]0, 1]
? 4 => uint, ; probability distribution
? 5 => number ; effective degrees of freedom
}
The tag content MUST be an array of two, three or four data items. Any other length is an error.
3.1 value
The reading of the physical quantity, scaled by prefix and expressed in
unit. It MUST be either
- a CBOR integer (major type 0 or 1),
- a bignum (tag 2 or 3), for an integer beyond the range of major type 0 or 1, or
- a decimal fraction (tag 4) whose mantissa is an integer or a bignum.
It MUST NOT be a binary floating-point number, and it MUST NOT be a bigfloat (tag 5). An integer that major type 0 or 1 can carry MUST NOT be written as a bignum — this is the preferred serialization of [RFC 8949], Section 3.4.3, and it keeps the encoding deterministic.
The exponent of a decimal fraction MUST be negative: a decimal fraction
states decimal places, and an integral reading is written as an integer (or
bignum). This gives every reading exactly one encoding — 500 has no
second spelling as 4([0, 500]) or 4([2, 5]) — and text input in
scientific notation whose exponent leaves no decimal places (5e2,
5.0e2) denotes the integer it equals. A resolution coarser than one is
not something this format states; a producer that needs it states an
uncertainty.
The decimal scale is significant: 4([-1, 50]) (= 5.0) and 5 denote the
same numeric quantity but different measurement resolutions, and both MUST
survive a decode/encode roundtrip unchanged.
3.2 unit
A named unit is either an unsigned integer identifying a unit of measure in the registry of Section 4, or a text string holding its symbol (or one of the aliases listed there). Encoders SHOULD use the numeric identification; decoders MUST accept both forms. A numeric identification greater than 65535, an unregistered identification and an unknown symbol are errors.
A product of powers is an array of [named-unit, exponent] factors, in
the order they are to be displayed. It expresses every derived quantity that
is not in the registry: m·s⁻² is [[15, 1], [8, -2]], and
W·m⁻²·K⁻¹ is [[3, 1], [15, -2], [17, -1]].
The exponent is an integer, or a [numerator, denominator] pair for a
rational power, and it MUST NOT be zero. A rational exponent MUST be in
lowest terms and its denominator MUST be greater than one: [-2, 4] and
[2, 1] are not valid spellings of [-1, 2] and 2, and decoders MUST
reject them rather than reduce them — a reading has one encoding, and a
signed document must not change its bytes on the way through a decoder.
Rational powers are not decoration: an amplitude spectral density is stated
per √Hz (V·Hz^-1/2), fracture toughness in Pa·m^1/2 and the Warburg
impedance in Ω·s^-1/2.
A single named unit MUST be written in the named form, never as a
one-element array with exponent one — the compact form is the one that
stays cheap on the wire, and a canonical encoding must not have two
spellings for the same unit. Decoders MUST reject [[unit, 1]].
Why not an existing unit vocabulary? SenML ([RFC 8428], with an IANA registry of its own), UCUM, QUDT and UN/CEFACT Recommendation 20 all define unit identifiers, and Section 4 lists the SenML symbol next to every entry so that a translation is mechanical. They are not used directly because this tag needs three properties at once that none of them provides together: a short integer identifier (a byte or two, not a string, because measurement data is transmitted in bulk), a prefix kept separate from the unit (Section 3.3), and stable numbering under our own control so that a value written today decodes identically in twenty years, which is the horizon calibration law works on.
3.3 prefix
The decimal power of the SI prefix by which value (and uncertainty) are
scaled: 3 for kilo, -3 for milli, -6 for micro. When absent, the prefix
is 0.
Only the 25 canonical SI prefix exponents are valid:
-30 -27 -24 -21 -18 -15 -12 -9 -6 -3 -2 -1 0 1 2 3 6 9 12 15 18 21 24 27 30
Any other exponent is an error; in particular, prefix is not a general
scaling factor.
The prefix applies to the quantity as a whole, not to an individual factor of
a compound unit: [3, [[15,1],[8,-2]]] with prefix 3 is km·s⁻², i.e. the
whole reading scaled by 10³, and not m·(ks)⁻².
Affine units. The degree Celsius is an interval scale: converting it to the kelvin needs an offset, not a factor. A prefix on such a unit therefore scales a temperature difference, never a thermodynamic temperature — a "m°C" reading is a difference of a thousandth of a degree, and nothing about it can be turned into kelvin by multiplication alone. Encoders SHOULD write absolute temperatures with prefix 0, and consumers MUST NOT convert a prefixed affine reading by scaling alone. The registry marks the affected units.
The prefix is deliberately kept separate from the value instead of being
folded into it: 5.00 mA is the reading of the instrument, 0.005 A is a
computation on it. Both denote the same quantity, but only the former
reproduces what was displayed and certified.
When uncertainty is present, prefix MUST be written explicitly, even when
it is 0, because the array is positional and uncertainty is trailing.
When no uncertainty follows, a prefix of 0 MUST be omitted — writing
it would give the same reading two encodings — and decoders MUST reject the
redundant form.
3.4 uncertainty
The symmetric measurement uncertainty associated with value, as defined
by the Guide to the Expression of Uncertainty in Measurement ([GUM],
JCGM 100:2008, BIPM). It is expressed in the same unit and the same
prefix as value and MUST NOT be negative.
A bare number is the standard uncertainty u, i.e. a coverage factor of 1, encoded per Section 3.1. This is the compact and by far the most common form.
A map states more. Its keys are:
| Key | Meaning |
|---|---|
| 1 | the magnitude, as reported (required) |
| 2 | the coverage factor k the magnitude belongs to (default 1) |
| 3 | the coverage probability, a fraction in ]0, 1] |
| 4 | the probability distribution (see below) |
| 5 | the effective degrees of freedom (positive) |
The standard uncertainty is always u = magnitude / k, and the coverage
factor MUST therefore be positive. A calibration certificate stating
U = 0.12 V with k = 2 is written as {1: 4([-2, 12]), 2: 2} and keeps
saying exactly that, instead of being normalised to u = 0.06 and losing the
statement the certificate was issued with. Consumers that only need u
divide by k.
A map that states only the magnitude MUST NOT be written: with the coverage factor at its default of 1 it says exactly what the bare number says, which would give the same uncertainty two encodings — and decoders MUST reject the redundant form.
Distributions (key 4): 1 = normal, 2 = rectangular, 3 = triangular, 4 = U-shaped, 5 = Student's t. 0 means "not stated" and MUST be omitted rather than written. The degrees of freedom are what a consumer needs to derive a coverage factor from a coverage probability ([GUM] Annex G).
A map key other than 1..5 MUST be rejected: an unknown key could state anything — an asymmetry, a correlation, a second magnitude — and dropping it would silently change what the uncertainty says.
Out of scope, deliberately: asymmetric uncertainties and correlations between quantities. A correlation is a property of a set of values, not of a single one, and belongs in the structure that carries them.
Rounding. [GUM] Section 7.2.6 recommends reporting a value with the number of digits its uncertainty justifies. This format performs no such rounding: it reproduces what the instrument reported, digit for digit (Section 3.1). Rounding is a presentation decision and stays with the producer.
4. Unit registry
The numeric identifications are stable and MUST NOT be renumbered. 0 is
reserved and never valid on the wire. Identifications 1..32767 are managed by
this specification; 32768 and above are available for private use and are not
interoperable outside the agreement of the communicating parties.
The single-byte range is allocated by frequency, not by taxonomy. CBOR encodes the identifications 1..23 in a single byte and everything from 24 onwards in two, so those 23 places are the scarcest thing this registry has to give away. They go to the units that dominate the traffic this format was built for — electric vehicle charging, metering and grid telemetry — which is why the watt-hour is identification 2 while the candela is 25. A taxonomic allocation, SI base units first and the named derived ones in textbook order, would have inverted exactly that.
The consequence is that the table below does not read in textbook order. That is the price, and it is paid once per value transmitted, forever.
Identification 1 is the dimensionless one, because it is the neutral element of unit multiplication and because its symbol is literally "1".
Taxonomy resumes above the byte boundary: 24..39 hold the remaining SI base and named derived units, 60..65 the remaining accepted non-SI units, 120..122 the data units and 140..141 the geometric ones. The ranges 40..59, 66..99, 100..119 and 123..139 are reserved for future registrations, so that a later addition never has to break the grouping.
| Id | CBOR | Symbol | Unit |
|---|---|---|---|
| 1 | 01 |
1 |
one (dimensionless) |
| 2 | 02 |
Wh |
watt-hour |
| 3 | 03 |
W |
watt |
| 4 | 04 |
A |
ampere |
| 5 | 05 |
V |
volt |
| 6 | 06 |
% |
percent |
| 7 | 07 |
°C |
degree Celsius |
| 8 | 08 |
s |
second |
| 9 | 09 |
Hz |
hertz |
| 10 | 0A |
var |
volt-ampere reactive |
| 11 | 0B |
VA |
volt-ampere |
| 12 | 0C |
Ah |
ampere-hour |
| 13 | 0D |
varh |
volt-ampere-reactive hour |
| 14 | 0E |
Ω |
ohm |
| 15 | 0F |
m |
meter |
| 16 | 10 |
g |
gram |
| 17 | 11 |
K |
kelvin |
| 18 | 12 |
h |
hour |
| 19 | 13 |
min |
minute |
| 20 | 14 |
J |
joule |
| 21 | 15 |
Pa |
pascal |
| 22 | 16 |
bit/s |
bit per second |
| 23 | 17 |
S |
siemens |
| — from here on an identification costs two bytes instead of one — | |||
| 24 | 1818 |
mol |
mole |
| 25 | 1819 |
cd |
candela |
| 26 | 181A |
N |
newton |
| 27 | 181B |
C |
coulomb |
| 28 | 181C |
F |
farad |
| 29 | 181D |
Wb |
weber |
| 30 | 181E |
T |
tesla |
| 31 | 181F |
H |
henry |
| 32 | 1820 |
lm |
lumen |
| 33 | 1821 |
lx |
lux |
| 34 | 1822 |
Bq |
becquerel |
| 35 | 1823 |
Gy |
gray |
| 36 | 1824 |
Sv |
sievert |
| 37 | 1825 |
kat |
katal |
| 38 | 1826 |
rad |
radian |
| 39 | 1827 |
sr |
steradian |
| 60 | 183C |
d |
day |
| 61 | 183D |
° |
degree |
| 62 | 183E |
l |
litre |
| 63 | 183F |
t |
tonne |
| 64 | 1840 |
‰ |
permille |
| 65 | 1841 |
ppm |
parts per million |
| 120 | 1878 |
bit |
bit |
| 121 | 1879 |
B |
byte |
| 122 | 187A |
B/s |
byte per second |
| 140 | 188C |
m² |
square meter |
| 141 | 188D |
m³ |
cubic meter |
Accepted symbol aliases: Metre (15), Ohm (14), Cel (7), deg (61),
L/Liter (62), one and / (1), bps (22), m2 (140), m3 (141).
Decoders MUST accept them; encoders SHOULD emit the symbol of the table above.
Dimensionless quantities use one (1): ratios, efficiencies, counts,
refractive indices. It is the coherent SI unit of a quantity of dimension
one, and a reading without a unit is not the same thing as a reading whose
unit is one.
Affine units (Section 3.3): °C (7). Prefixes on it denote temperature
differences.
SenML. Where a unit also exists in the IANA "SenML Units" registry
([RFC 8428]), the symbol is either identical (m, A, W, V, Hz, Wh,
VA, var, bit, ppm) or an accepted alias of ours (Cel → 7,
/ → 1). The mapping is therefore mechanical in both directions for the
overlapping subset; SenML's %RH and its /100 convention for percent have
no counterpart here, and this format's percent (6) is the plain
dimensionless ratio.
Note on mass. The SI base unit of mass is the kilogram, but SI prefixes
attach to the gram. The registry therefore contains the gram (16), and a
mass of five kilograms is encoded as (5, 16, 3) — five, gram, kilo.
Note on implementations. This registry is the wire vocabulary, not a list of types an implementation has to provide. A decoder needs the identifier and the symbol; whether it also offers a dedicated class per unit is its own business. The reference implementation, for instance, has purpose-built types for the eighteen units its applications work with and carries every other registered unit through its generic metrological value. Nothing about a unit having no dedicated type restricts what may be sent.
5. Examples
| Reading | Encoding |
|---|---|
5 A |
D9ACDC 82 05 04 |
230 V |
D9ACDC 82 18E6 05 |
5.0 mA |
D9ACDC 83 C482201832 04 22 |
1.10 kWh |
D9ACDC 83 C48221186E 02 03 |
(5.00 ±0.02) mA |
D9ACDC 84 C482211901F4 04 22 C4822102 |
(5 ±0.5) A |
D9ACDC 84 05 04 00 C4822005 |
5.0 mA, symbolic unit |
D9ACDC 83 C482201832 6141 22 |
9.81 m·s⁻² |
D9ACDC 82 C482211903D5 82 820F01 820821 |
(230.00 ±0.12) V, k=2 |
D9ACDC 84 C482211959D8 05 00 A201C482210C0202 |
4.5 nV·Hz^-1/2 |
D9ACDC 83 C48220182D 82 820501 820982200228 |
Byte-level breakdown of 5.0 mA:
D9 ACDC tag(44252)
83 array(3)
C4 tag(4), decimal fraction
82 array(2)
20 -1 exponent
18 32 mantissa 50 -> 50 * 10^-1 = 5.0
04 4 unit: ampere
22 -3 prefix: milli
In diagnostic notation ([RFC 8949], Section 8) this reads as
44252([4([-1, 50]), 4, -3]).
Note the (5 ±0.5) A row: the prefix 00 is present although it is zero,
because the uncertainty follows it.
6. Deterministic encoding
Tag 44252 imposes no requirements of its own beyond the Core Deterministic Encoding Requirements of [RFC 8949], Section 4.2.1, which it fully supports: the encoding of a given metrological value is a function of its value, scale, unit, prefix and uncertainty alone. This keeps measurement data suitable for signing, e.g. with COSE ([RFC 9052]).
That suitability grows rather than fades as signatures do. A signature travels as a byte string, which costs its own length and a head of one to three bytes; a textual encoding has to spell the same bytes out, typically in base64, at a third again their size — and by then the signature, not the measurement, is the largest field in the message. A reading is tens of bytes and a signature may be thousands, so the ratio only points one way.
The value-level uniqueness rules — one spelling per reading (Section 3.1), per exponent and per unit (Section 3.2), per prefix (Section 3.3), per uncertainty (Section 3.4) — are decoder MUSTs of their sections. For the byte level beneath them (shortest integer heads, definite lengths, sorted map keys, preferred bignums) two decoder profiles exist: a strict decoder verifies deterministic encoding and rejects what violates it, which is the profile this specification RECOMMENDS; a lenient decoder MAY accept non-deterministic bytes where it has to read documents from producers beyond its control. A lenient decoder MUST NOT reproduce non-deterministic bytes when re-encoding.
The same reasoning reaches past this tag, to the structure that carries it. A signature covers bytes rather than meaning, so a document that will be signed SHOULD be written in the deterministic encoding of [RFC 8949], Section 4.2.1 throughout — not merely in the readings it holds. A consumer that receives such a document, decodes it and encodes it again produces that encoding; where the signer wrote a different spelling of the same data, the re-encoded document no longer verifies, and the failure is indistinguishable from tampering. This is a property of the carrier rather than of the tag, which is why it is a SHOULD here and not a MUST: this specification cannot bind a format it does not define. The worked example of this specification (tag-44252-signed-example.md) is written that way.
Two readings that denote the same physical quantity in different
representations (5.0 mA and 0.005 A) intentionally do not produce the
same bytes. Implementations that need to compare quantities rather than
representations should compare mantissa and total exponent, which is exact
and unbounded, rather than converting to a common prefix, which can overflow.
6a. What this tag does not carry
A tag annotates one data item, so this one describes a quantity value with its unit and its uncertainty — and nothing else. The following belong to the structure that carries the value, typically a CBOR map holding it alongside its siblings:
- The kind of quantity.
N·mandJhave the same dimension but are torque and energy; [VIM] Section 1.2 calls this the kind of quantity, and no unit can express it. A consumer that needs the distinction must carry it next to the value. - Traceability metadata: the instant of measurement, the instrument, the calibration certificate it traces to, the operator, the measurement procedure. The [DCC] models these; this tag is what such a model would use for the numbers inside it.
- Correlations between quantities, for the reason given in Section 3.4.
This is a deliberate division of labour, not an omission: a value tag that also carried provenance would be unusable as the leaf of somebody else's schema.
7. Security considerations
The security considerations of [RFC 8949] apply. In addition:
- Decoders MUST reject unknown unit identifications rather than substituting a placeholder: a value silently attributed to the wrong unit is worse than a decoding failure.
- Decimal fractions permit very large exponents, and bignums — as values and as mantissas — very large integers. Decoders MUST bound the resources spent on reconstructing a value and reject values they cannot represent exactly, rather than rounding silently.
- A missing
uncertaintymeans "not stated", never "zero".
8. IANA considerations
Tag 44252 (0xACDC) is registered in the "Concise Binary Object
Representation (CBOR) Tags" registry ([RFC 8949], Section 9.2), assigned on
2026-08-19 under that registry's First Come First Served policy. This
document is the "Description of semantics" the entry points at.
The entry as published, quoted from the registry rather than from the request:
Tag: 44252
Data item: array
Semantics: Metrological value (quantity value with unit of measure, SI prefix
and GUM measurement uncertainty)
Reference: https://github.com/OpenChargingTechnology/Whitepapers/blob/master/MetrologicalCBOR/README.md
Achim Friedland
Template: template/44252
https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
9. References
- [RFC 8949] C. Bormann, P. Hoffman, Concise Binary Object Representation (CBOR), STD 94, December 2020. https://www.rfc-editor.org/rfc/rfc8949
- [RFC 8610] H. Birkholz, C. Vigano, C. Bormann, Concise Data Definition Language (CDDL), June 2019. https://www.rfc-editor.org/rfc/rfc8610
- [RFC 9052] J. Schaad, CBOR Object Signing and Encryption (COSE): Structures and Process, STD 96, August 2022. https://www.rfc-editor.org/rfc/rfc9052
- [RFC 8428] C. Jennings, Z. Shelby, J. Arkko, A. Keränen, C. Bormann, Sensor Measurement Lists (SenML), August 2018. https://www.rfc-editor.org/rfc/rfc8428 — see also the IANA "SenML Units" registry.
- [GUM] JCGM 100:2008, Evaluation of measurement data — Guide to the expression of uncertainty in measurement, BIPM. https://www.bipm.org/en/committees/jc/jcgm/publications
- [VIM] JCGM 200:2012, International vocabulary of metrology — Basic and general concepts and associated terms (VIM), 3rd edition, BIPM.
- [SI] BIPM, The International System of Units (SI), 9th edition, 2019 (SI prefixes as extended in 2022 by CGPM Resolution 3).
Related work
- D-SI, the Digital System of Units of the EMPIR project SmartCom (17IND02), a metadata format for the machine-readable exchange of metrological data covering real, complex, vector and constant quantities. https://zenodo.org/records/10230771
- [DCC] The Digital Calibration Certificate of PTB, which models a calibration certificate end to end. https://www.ptb.de/dcc/
Both are XML-based and considerably broader in scope than this tag: they describe whole documents, this describes one number. The intent here is to be the compact binary leaf such a model can carry — which is why Section 6a keeps provenance out and Section 3.4 keeps the coverage factor in.