apache/druid · warning · ParseException

Unable to parse [%s] as the intermediateRow resulted in empt

Error message

Unable to parse [%s] as the intermediateRow resulted in empty input row

What it means

After JsonReader.parseInputRows collects rows from a JSON record, an empty result triggers a ParseException ('Unable to parse [ ... ] as the intermediateRow resulted in empty input row') echoing the raw input. Like other Druid ParseExceptions this marks the record unparseable so it is counted/skipped rather than crashing the task.

Source

Thrown at processing/src/main/java/org/apache/druid/data/input/impl/JsonReader.java:144

        final JsonNode row = delegate.next();
        inputRows.add(MapInputRowParser.parse(inputRowSchema, flattener.flatten(row)));
      }
    }
    catch (RuntimeException e) {
      //convert Jackson's JsonParseException into druid's exception for further processing
      //JsonParseException will be thrown from MappingIterator#hasNext or MappingIterator#next when input json text is ill-formed
      if (e.getCause() instanceof JsonParseException) {
        final String rowAsString = IOUtils.toString(entity.open(), StandardCharsets.UTF_8);
        throw new ParseException(rowAsString, e, "Unable to parse row [%s]", rowAsString);
      }

      //throw unknown exception
      throw e;
    }

    if (inputRows.isEmpty()) {
      final String rowAsString = IOUtils.toString(entity.open(), StandardCharsets.UTF_8);
      throw new ParseException(
          rowAsString,
          "Unable to parse [%s] as the intermediateRow resulted in empty input row",
          rowAsString
      );
    }

    return inputRows;
  }

  @Override
  protected List<Map<String, Object>> toMap(InputEntity entity) throws IOException
  {
    try (JsonParser parser = jsonFactory.createParser(entity.open())) {
      final MappingIterator<Map> delegate = mapper.readValues(parser, Map.class);
      return FluentIterable.from(() -> delegate)
                           .transform(map -> (Map<String, Object>) map)
                           .toList();
    }

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Check the echoed raw row to identify the empty/null record
  2. Scrub null/empty lines from the source or fix the producer
  3. Adjust the parse spec so such records produce a row (e.g. flattenSpec) if they should be ingested
  4. Accept skipping: ensure maxParseExceptions/task logs are configured to tolerate skipped records

Example fix

// before: stream contains bare 'null' lines -> empty row
// after: preprocess input
//   grep -v '^null$' input.ndjson > cleaned.ndjson
Defensive patterns

Strategy: try-catch

Validate before calling

// Detect records that flatten to nothing before ingestion
JsonNode node = objectMapper.readTree(raw);
if (node == null || node.isNull() || node.isEmpty()) { skip(raw); }

Type guard

static boolean producesNoRow(JsonNode node) { return node == null || node.isNull() || (node.isContainerNode() && node.isEmpty()); }

Try / catch

try { rows = reader.read().collect(toList()); } catch (ParseException e) { deadLetterQueue.add(e.getMessage()); /* record echoes raw input; inspect and reprocess */ }

Prevention

When it happens

Trigger: A record deserializes successfully but yields zero InputRows — e.g. a null JSON value, an empty object/array filtered out by the parser, or records whose flattened content is entirely discarded.

Common situations: Producers emitting null placeholder lines in NDJSON streams; empty objects {} in the data; upstream systems writing tombstone records; last truncated line of a file.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/7a3cf4107bc6aa48. Report an issue: GitHub.