InfluxDB receives the MQTT message through a consumer before Flux evaluates r._value. Follow the packet from publisher to broker, from broker to consumer, and then into json.parse. The supplied payload reaches the parsing stage with invalid JSON delimiters: the PointName key lacks an opening quote, and several fields use typographic quotation marks instead of JSON double quotes.
Where does the MQTT data path stop?
The path has four functional stages: an MQTT publisher serializes the payload, the broker transports it, the consumer places the payload in a record, and Flux converts r._value to bytes for the JSON parser. A parser error after r._value exists points downstream of MQTT transport. A missing record points upstream toward the broker connection, subscription, or physical network.
| Path item | Reading to take | Meaning | Next check |
|---|---|---|---|
| Broker address | Read the configured address from the consumer | A connection failure prevents any payload from reaching Flux | Verify link and broker reachability |
| Broker port | Compare the consumer setting with the broker listener | A mismatch stops the connection before JSON processing | Correct the connection setting |
| Subscription | Confirm that records arrive for the configured topic | No record means the parser has nothing to process | Trace publishing and subscription |
| Payload field | Inspect the exact contents of r._value
|
A populated value moves the fault boundary to decoding or parsing | Validate the raw bytes |
| Message time | Compare receipt time with 2020-05-09T13:35:08.026Z
|
A large difference may indicate delayed or retained data | Decide which timestamp should become the point time |
Do not change broker settings when the consumer already exposes the failing payload. MQTT transports bytes; it does not repair JSON syntax or convert a unit-bearing string into a numeric field.
Is layer one delivering the payload intact?
Check the physical and transport path before interpreting a parser message. Confirm that the consumer receives complete records rather than truncated payloads, reconnect fragments, or an empty value. Compare the received byte count and content with the publisher output. The first and last braces, every quotation mark, and the complete timestamp must arrive unchanged.
If no record appears, inspect link state, interface counters, name resolution when a hostname is configured, TCP connection state, broker authentication, and topic subscription. If a record appears but its bytes differ from the publisher output, capture both sides of the broker path. If the bytes match, stop troubleshooting the network and continue at JSON syntax.
Pay particular attention to character encoding. JSON structural quotation marks are the ASCII double-quote character ". Typographic left and right quotation marks may display similarly in an editor, but a JSON parser treats them as ordinary non-structural characters. Copying a payload through formatted text can introduce this fault even when MQTT carries every byte correctly.
Is the received value valid JSON?
The original object is malformed at its first key and uses typographic quotes around later keys and values. Colons, slashes, underscores, spaces, and the text PERCENT are allowed inside JSON strings; they are not the syntax fault. Raw control characters such as a literal newline or tab inside a string are invalid. A producer that needs those characters must emit their JSON escape forms rather than raw control bytes.
| Element | Received form | Required interpretation |
|---|---|---|
| First key | PointName" |
Add the missing opening ASCII quote |
| Remaining delimiters | Typographic quotation marks | Replace them with ASCII JSON quotes |
Valeur |
"52.1 PERCENT" |
Valid string, but not a numeric field |
time |
"2020-05-09T13:35:08.026Z" |
Valid JSON string; timestamp conversion is a separate step |
A syntactically corrected payload is:
{
"PointName": "ac:Data/ATA/ATA_3/Capteurs/Hygro_Ambiante/PresentValue",
"Valeur": "52.1 PERCENT",
"time": "2020-05-09T13:35:08.026Z"
}
Validate the exact bytes produced by the publisher, not a reformatted copy. If validation fails, correct serialization at the publisher. Replacing characters in the consumer can mask a producer defect and may alter legitimate data.
Can Flux parse the corrected _value?
The documented v2.0.3 case uses experimental/json and converts r._value to bytes before parsing. Test parsing before adding unit conversion, timestamp conversion, or database-field mapping:
import "experimental/json"
data
|> map(fn: (r) => {
jsonData = json.parse(data: bytes(v: r._value))
return {
_time: r._time,
_field: r._field,
PointName: jsonData.PointName,
Valeur: jsonData.Valeur,
time: jsonData.time,
}
})
If the import or function is unavailable, read the installed product version and its function inventory rather than substituting an assumed package name. If byte conversion fails, inspect the runtime type of r._value. If parsing fails while the same bytes pass a strict JSON validator, compare the parser input byte-for-byte with the validated sample; hidden control characters and altered quotes commonly explain the difference.
Are the parsed values suitable for InfluxDB fields?
Successful JSON parsing produces values according to their JSON types. PointName, Valeur, and time are strings in the corrected object. The value 52.1 PERCENT cannot be written as a numeric measurement without separating the number from the unit.
| Source member | Parsed type | Decision |
|---|---|---|
PointName |
String | Map it to the destination identity or metadata field selected by the schema |
Valeur |
String | Store it as text, or split and validate 52.1 before numeric conversion |
time |
String | Parse it explicitly if source time must replace r._time
|
Reject or quarantine values whose numeric token or unit does not match the expected schema. Silently stripping arbitrary suffixes can turn malformed sensor data into plausible numbers. Decide whether the MQTT event time or consumer receipt time controls _time, then apply that rule consistently.
What procedure fixes and verifies the parsing path?
- Capture the publisher payload and the consumer’s exact
r._value. Compare the bytes, including braces, quotation marks, and control characters. - If no consumer record exists, verify the physical link, broker address, broker port, authentication, and subscription. Continue only after the complete payload reaches the consumer.
- Change the publisher serializer so every key and string uses ASCII double quotes. Add the missing opening quote before
PointName, and emit escaped forms for any newline or tab contained in a string. - Run the corrected payload through
json.parse(data: bytes(v: r._value))in the v2.0.3 environment described above. First return the three parsed members without additional transformations. - Choose the destination types. Keep
Valeuras a string or validate and convert its numeric token while handlingPERCENTseparately. Converttimeonly when it is selected as the point timestamp. - Publish a known sample and verify that the resulting record contains the complete
PointName, the intended value type, and the selected timestamp. Compare the stored result with52.1 PERCENTand2020-05-09T13:35:08.026Z.
FAQ
Why does MQTT deliver the message but JSON parsing fails?
MQTT transports the payload as bytes and does not validate JSON. The shown payload has a missing opening quote before PointName and uses typographic quotes, so transport can succeed while json.parse fails.
Why does 52.1 PERCENT parse as a string?
The value is enclosed in quotes and contains a unit, so its JSON type is string. Split and validate the numeric token before converting it, or retain the complete value as text.
Why does parsed MQTT time differ from the stored point time?
The mapped record retains r._time unless the parsed time string is explicitly converted and assigned. Publish one known sample, then verify that the stored timestamp equals 2020-05-09T13:35:08.026Z when source time is the selected policy.