CNA-BUG-210: A diagnostics name or resource label longer than 4,096 bytes makes every Inspector snapshot or event batch that contains it fail with LimitExceeded
Evidence basis: source-verified at the pinned commit; executed for this entry (the Evidence section names exactly what was run); tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit 009d40f5; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.
Diagnostics accepts names up to 1 MiB and labels of any length, but the Inspector protocol caps strings at 4,096 bytes and refuses the whole response, so one long name breaks the affected Inspector views for the rest of the process.
- Identifier
CNA-BUG-210- Category
- Bug
- Subsystem
- Diagnostics & Inspector
- Status
- Open
- Verified against
- CNA
009d40f5(009d40f5dd085c4e674d3479675fac84b12b3e0a) - Severity
- Low (a triage suggestion, not a project priority)
- Evidence basis
- Reproduced: executed for this entry (the Evidence section names exactly what was run)
- Tests touching this area
- Yes: see Current tests
- Affected contract
- CNA::Inspector protocol v1 SnapshotResponse and EventsResponse encoding (ProtocolCodec::Encode) over diagnostics provider v1 data
Expected behaviour
The Inspector is a consumer of the unchanged provider v1 contract, and inspector.md says oversized complete snapshots are refused rather than partially mislabeled. That refusal policy is therefore intended, but it should be predictable: either the two modules agree on one string bound that registration enforces and the documentation states, or the refusal is limited to the offending item instead of every snapshot and event batch that contains it.
Actual behaviour at TARGET
RegisterMetric and RegisterName accept names up to MaximumTraceNameBytes (1 MiB); CopyResource copies labels and formats without a bound. Protocol.cpp's Writer::String throws std::length_error above MaximumStringBytes (4,096) for metric names (WriteMetric, including per-frame metrics), resource label and format (WriteResource) and resolved event names, and Agent::Impl::HandleRequest turns that into ErrorCode::LimitExceeded for the whole request. Metrics are never unregistered, so the overview request (metrics and frames) fails for the rest of the process; the Resources view fails while such a resource lives, and each event batch containing such a name fails. docs/inspector.md says oversized complete snapshots are refused rather than partially mislabeled, but neither states the 4,096-byte bound nor offers a remedy for a long name (its troubleshooting line says only “reduce event count or preview bounds”). Engine labels are short literals ("Texture2D"), so the trigger is application instrumentation.
Source locations
modules/diagnostics/src/Diagnostics.cpp— MaximumTraceNameBytes; RegisterMetric, RegisterName, CopyResourcemodules/inspector/src/Protocol.cpp— MaximumStringBytes; Writer::String, WriteMetric, WriteResource, Encode(EventsResponse)modules/inspector/src/Agent.cpp— Agent::Impl::HandleRequest maps length_error to LimitExceededdocs/inspector.md— Troubleshooting: Limit error
Evidence
Read at 009d40f5. Executed: TARGET's Diagnostics.cpp and Protocol.cpp compiled unchanged with g++ 14.2 -std=c++23 -DCNA_DIAGNOSTICS_LEVEL=2 (both need only the standard library) and driven directly: a 5,000-byte counter name registered (non-zero id) and ProtocolCodec::Encode of a metrics snapshot threw length_error; a 5,000-byte resource label registered and the resources snapshot threw likewise. The agent round trip and the browser view were not run; the mapping to LimitExceeded is by reading.
Independent re-verification: Reproduced by the audit at 009d40f5. TARGET's Diagnostics.cpp and Protocol.cpp were compiled unchanged (g++ -std=c++23 -DCNA_DIAGNOSTICS_LEVEL=2) and driven directly: a 4,096-byte counter name encoded, while 4,097-byte and 5,000-byte counter names, a 5,000-byte resource label and a 5,000-byte resolved event name were all registered (non-zero id) and made ProtocolCodec::Encode throw length_error; registration accepts exactly 1 MiB and refuses 1 MiB plus one byte. The agent round trip and the browser view were not run; the mapping to LimitExceeded is by reading Agent.cpp. inspector.md documents the refusal of oversized complete snapshots but neither the 4,096-byte string bound nor its remedy.
Focused reproduction
Compiled and run as described under Evidence.
using namespace CNA::Diagnostics;
(void)SetRuntimeMode(Mode::Stats);
CounterHandle counter(std::string(5000, 'n')); // accepted: id != 0
CNA::Inspector::SnapshotResponse response;
response.includedParts = static_cast<std::uint32_t>(CNA::Inspector::SnapshotPart::Metrics);
response.snapshot = GetProvider().CaptureSnapshot();
(void)CNA::Inspector::ProtocolCodec::Encode(response, 1);
// throws std::length_error: "Inspector string exceeds its protocol bound"
Current tests
InvalidIdentityStringsFailBeforeProviderAccess covers the agent's own identity strings (a 4,097-byte application name is refused at Start); protocol tests cover oversized input on decode. No test feeds a provider-valid long name or label.
Regression test
An InspectorAgentTests case whose fake provider returns a 5,000-byte metric name and resource label, asserting the documented handling (truncation or per-item omission) instead of a whole-response LimitExceeded; or a diagnostics test that registration refuses names above the Inspector's bound.
Blast radius
Applications whose own instrumentation registers long (for example generated) names or labels, and their Inspector sessions; the diagnostics core and in-process consumers are unaffected.
Workaround
Keep diagnostic names and labels under 4,096 bytes.
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- User guide
- Inspector: troubleshooting · Inspector: protocol
- Internals
- Inspector internals: bounds
- Known issues
- Bug index