Skip to content

[BUG] Elasticsearch exporter decides bulk success by substring instead of the errors field #4295

Open

Description

@thc1006

Both export paths decide whether a bulk write succeeded by looking for a substring in the response body.

if (body_.find("\"failed\" : 0") == std::string::npos)

if (responseBody.find("\"failed\" : 0") == std::string::npos)

if (body_.find("\"failed\" : 0") == std::string::npos)

Three problems with that test.

failed is not the bulk outcome. In a bulk response, failed appears under _shards for an individual item. The result for the batch as a whole is the top level errors boolean. A body where one item has "failed": 0 and another item failed outright still matches the substring and is reported as a success.

It depends on pretty-printed spacing. The literal contains " : ". Elasticsearch only formats that way when the request asks for it, so a compact response never matches and a completely successful export is reported as a failure.

The asynchronous path ignores the HTTP status. AsyncResponseHandler::OnResponse only inspects the body, so a 4xx or 5xx with a body that happens to contain the substring is treated as a success. The synchronous path does check the status, in ResponseHandler::OnResponse.

Suggested fix

Parse the body and check the top level errors field, and check the HTTP status on both paths. nlohmann/json.hpp is already included by this file and already linked in both the CMake and Bazel targets, so this needs no new dependency. A malformed or unparseable body should count as a failure rather than being ignored.

I would like to work on this one.

Activity

  1. added
    needs-triageIndicates an issue or PR lacks a `triage/foo` label and requires one.
    on Jul 24, 2026
  2. added 5 commits that reference this issue on Jul 24, 2026
    56856fa
    4eba0cc
    30e2f32
    04357c7
    229ee19
  3. github-actions commented on Sep 24, 2026

    @github-actions

    This issue was marked as stale due to lack of activity.

  4. thc1006 commented on Oct 2, 2026

    @thc1006
    MemberAuthor

    Still present on main at e4232d8e: both call sites decide from find("\"failed\" : 0") as before, and errors does not appear anywhere in es_log_record_exporter.cc.

    #4297 carries the fix and is based on current main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageIndicates an issue or PR lacks a `triage/foo` label and requires one.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions