apache/hadoop · warning · NoRecordException

No data at path

Error message

No data at path

What it means

JsonSerDeser.fromBytes(path, bytes, marker) deserializes registry znode payloads. A zero-length byte array means the path holds no record at all, so it throws NoRecordException (an IOException subclass) with 'No data at path' — deliberately distinct from InvalidRecordException, which signals corrupt data.

Source

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

   * will be verified before the JSON parsing takes place; it is a fast-fail
   * check. If not found, an {@link InvalidRecordException} exception will be
   * raised
   * @param path path the data came from
   * @param bytes byte array
   * @param marker an optional string which, if set, MUST be present in the
   * UTF-8 parsed payload.
   * @return The parsed record
   * @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. Treat NoRecordException as 'record absent', not as corruption: catch it and return Optional.empty() or retry later
  2. Write records atomically — create the znode together with its payload instead of create-then-set-data
  3. Guard reads by znode size: skip nodes whose stat.size is 0 (the pattern RegistryUtils itself uses before reading records)

Example fix

// before
byte[] bytes = registryOps.stat(path) != null ? zkGetData(path) : null;
ServiceRecord r = marshal.fromBytes(path, bytes, marker); // empty node -> NoRecordException

// after
if (bytes == null || bytes.length == 0) {
  return Optional.empty();
}
ServiceRecord r = marshal.fromBytes(path, bytes, marker);
Defensive patterns

Strategy: validation

Validate before calling

if (bytes == null || bytes.length == 0) {
  return Optional.empty(); // znode holds no record yet
}
return Optional.of(marshal.fromBytes(path, bytes, marker));

Try / catch

try {
  return Optional.of(marshal.fromBytes(path, bytes, marker));
} catch (NoRecordException e) {
  return Optional.empty(); // 'No data at path' — node exists but holds no record
} catch (InvalidRecordException e) {
  throw e; // genuinely corrupt payload — do not swallow
}

Prevention

When it happens

Trigger: Reading a ZooKeeper znode that was created empty (create without data): placeholder/parent nodes created before the ServiceRecord is written, or a path that exists but has never been populated.

Common situations: Registry clients polling a service entry the publisher has not written yet; znodes created by mkdir-style helpers with no payload; tests stubbing ZK reads with empty arrays.

Related errors


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