Skip to content

[EXPORTER] Fix Elasticsearch log exporter aborting on invalid UTF-8 - #4501

Open
om7057 wants to merge 2 commits into
open-telemetry:mainfrom
om7057:fix/elasticsearch-invalid-utf8-abort
Open

[EXPORTER] Fix Elasticsearch log exporter aborting on invalid UTF-8#4501
om7057 wants to merge 2 commits into
open-telemetry:mainfrom
om7057:fix/elasticsearch-invalid-utf8-abort

Conversation

@om7057

@om7057 om7057 commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Fixes #4439

Summary

A log record's body or attributes may carry bytes that are not valid UTF-8 (a truncated multibyte sequence, a payload read in another encoding, a message built from a file path, etc). ElasticSearchRecordable::WriteValue stores the value as given, without validating or transcoding it. Export() then called nlohmann::json::dump() with its default strict error handler, which throws type_error.316 on invalid UTF-8. Since Export() is noexcept, that throw becomes std::terminate(), aborting the whole process rather than just failing the one export.

Fix

Switch to error_handler_t::replace, which substitutes U+FFFD for the invalid bytes instead of throwing. The record (and the rest of the bulk batch) is still exported, with just the invalid bytes replaced.

Test plan

  • Added ElasticsearchLogsExporterTests.ExportingARecordWithInvalidUtf8DoesNotAbort, using a fake injectable HttpClient/Session/Request/Response (the exporter already supports client injection) so the test doesn't need a real Elasticsearch instance.
  • Verified the test actually catches the regression: reverting the fix locally reproduces the exact std::terminate/abort from the issue.
  • Full es_log_record_exporter_test suite passes (3 tests, 3 pre-existing disabled tests unaffected).

A log record's body or attributes may carry bytes that are not valid UTF-8
(e.g. a truncated multibyte sequence, a payload read in another encoding, or
a string built from a file path). ElasticSearchRecordable::WriteValue stores
the value as given, without validating or transcoding it. Export() then
called nlohmann::json::dump() with its default strict error handler, which
throws on invalid UTF-8; since Export() is noexcept, that throw became
std::terminate() and aborted the whole process, not just the one export.

Switch to error_handler_t::replace, which substitutes U+FFFD for the invalid
bytes instead of throwing, so the record (and the rest of the batch) is still
exported.

Fixes open-telemetry#4439
@om7057
om7057 requested a review from a team as a code owner August 30, 2026 07:57
@codecov

codecov Bot commented Aug 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.45%. Comparing base (8074e35) to head (17a8218).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #4501      +/-   ##
==========================================
+ Coverage   83.22%   83.45%   +0.23%     
==========================================
  Files         521      521              
  Lines       20404    20405       +1     
==========================================
+ Hits        16980    17027      +47     
+ Misses       3424     3378      -46     
Files with missing lines Coverage Δ
...orters/elasticsearch/src/es_log_record_exporter.cc 47.73% <100.00%> (+35.52%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

…ctor>

The fake Response's ForEachHeader overrides use nostd::function_ref directly;
it was only reaching the test via a transitive include. <memory> and <vector>
are only used transitively too and iwyu wants them dropped.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] A log record with invalid UTF-8 aborts the process in the Elasticsearch exporter

1 participant