apache/hadoop · error · NoRecordException

Missing marker string: %s

Error message

Missing marker string: %s

What it means

fromBytes(path, bytes, marker) verifies the payload represents the expected record type by checking that the marker substring occurs in the UTF-8 decoded JSON. Registry code passes ServiceRecord.RECORD_TYPE ('JSONServiceRecord') as the marker; if the text does not contain it, NoRecordException ('Missing marker string: <marker>') is thrown instead of attempting a parse.

Source

Thrown at hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/binding/JsonSerDeser.java:108

   * @throws IOException all problems
   * @throws EOFException not enough data
   * @throws InvalidRecordException if the JSON parsing failed.
   * @throws NoRecordException if the data is not considered a record: either
   * it is too short or it did not contain the marker string.
   */
  public T fromBytes(String path, byte[] bytes, String marker)
      throws IOException {
    int len = bytes.length;
    if (len == 0 ) {
      throw new NoRecordException(path, E_NO_DATA);
    }
    if (StringUtils.isNotEmpty(marker) && len < marker.length()) {
      throw new NoRecordException(path, E_DATA_TOO_SHORT);
    }
    String json = new String(bytes, 0, len, StandardCharsets.UTF_8);
    if (StringUtils.isNotEmpty(marker)
        && !json.contains(marker)) {
      throw new NoRecordException(path, E_MISSING_MARKER_STRING + marker);
    }
    try {
      return fromJson(json);
    } catch (JsonProcessingException e) {
      throw new InvalidRecordException(path, e.toString(), e);
    }
  }

}

View on GitHub (pinned to 2add963021)

Solutions

  1. Match reader to format: check json.contains(marker) or the record's 'type' field before calling fromBytes with a marker
  2. For nodes that are legitimately non-record data, call fromBytes without a marker (an empty marker skips all three NoRecord checks) or read raw bytes
  3. If the node should be a record, rewrite it from a marshalled ServiceRecord (JsonSerDeser.toBytes stamps the type field)

Example fix

// before
ServiceRecord r = marshal.fromBytes(path, bytes, ServiceRecord.RECORD_TYPE);

// after
String json = new String(bytes, StandardCharsets.UTF_8);
if (!json.contains(ServiceRecord.RECORD_TYPE)) {
  return Optional.empty(); // foreign payload, not a service record
}
ServiceRecord r = marshal.fromBytes(path, bytes, ServiceRecord.RECORD_TYPE);
Defensive patterns

Strategy: try-catch

Validate before calling

String json = new String(bytes, StandardCharsets.UTF_8);
if (StringUtils.isNotEmpty(marker) && !json.contains(marker)) {
  return Optional.empty(); // foreign payload, not the expected record type
}
return Optional.of(marshal.fromBytes(path, bytes, marker));

Try / catch

try {
  return Optional.of(marshal.fromBytes(path, bytes, ServiceRecord.RECORD_TYPE));
} catch (NoRecordException e) {
  // 'Missing marker string' — node is valid data but not a ServiceRecord
  LOG.debug("Non-record node at {}: {}", path, e.toString());
  return Optional.empty();
} catch (IOException e) {
  throw new IOException("Failed to read record at " + path, e);
}

Prevention

When it happens

Trigger: A znode holding valid JSON that is not a ServiceRecord (different schema, user-written node), data written by a different serializer version, or hand-edited payloads read with the record marker.

Common situations: Reading user-written nodes (some registry entries are intentionally non-record data) with the record reader; schema drift between writer and reader versions; tests using arbitrary JSON fixtures where the 'type' field was renamed or removed.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/49026848f4707a48. Report an issue: GitHub.