Skip to content

out_s3, out_chronicle: grow log_key buffer to avoid dropping oversized values#12137

Open
vitaly-sinev wants to merge 2 commits into
fluent:masterfrom
vitaly-sinev:out-plugins-log-key-grow
Open

out_s3, out_chronicle: grow log_key buffer to avoid dropping oversized values#12137
vitaly-sinev wants to merge 2 commits into
fluent:masterfrom
vitaly-sinev:out-plugins-log-key-grow

Conversation

@vitaly-sinev

@vitaly-sinev vitaly-sinev commented Jul 22, 2026

Copy link
Copy Markdown

Problem

The log_key extraction paths in out_s3 and out_chronicle allocate a scratch buffer of bytes + bytes / 4 once and never grow it. When the selected log_key value is a non-string (number/array/object) whose JSON encoding does not fit in the remaining space, flb_msgpack_to_json() fails and the code simply breaks out of the loop:

ret = flb_msgpack_to_json(val_buf + val_offset, msgpack_size - val_offset, &val, ...);
if (ret < 0) {
    break;
}

As a result the oversized value is silently dropped (and, depending on timing, could previously be emitted truncated). This is a pre-existing data-loss bug independent of any formatting change.

Fix

Grow the scratch buffer and retry the conversion until the value fits, so an oversized log_key value is neither truncated nor dropped. The retry also guards the remaining size so flb_msgpack_to_json() is never called with a zero-length buffer.

  • out_s3: on allocation failure it uses the function's existing alloc_error path.
  • out_chronicle: on allocation failure it frees and returns NULL.

Testing

  • Builds cleanly with -DFLB_OUT_S3=On -DFLB_OUT_CHRONICLE=On (full fluent-bit binary).

Context

Surfaced during review of #12129 / #12133. #12133 makes flb_msgpack_to_json() signal truncation as a negative value (matching its contract); this PR makes these two callers actually recover from it. The two PRs are independent — this fix works whether the helper returns 0 or -1 on overflow (it checks ret <= 0).


Fluent Bit is licensed under Apache 2.0, by submitting this pull request I understand that this code will be released under the terms of that license.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of oversized log values during msgpack-to-JSON serialization for Chronicle and S3 outputs.
    • Added automatic retry with a growable scratch buffer to avoid truncation or dropped values.
    • Improved safety when additional memory can’t be allocated by aborting cleanly so the chunk can be retried rather than emitting partial payloads.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5a7e105d-f7d7-4ef9-af31-90687e019e70

📥 Commits

Reviewing files that changed from the base of the PR and between f25bf78 and 032f864.

📒 Files selected for processing (2)
  • plugins/out_chronicle/chronicle.c
  • plugins/out_s3/s3.c
🚧 Files skipped from review as they are similar to previous changes (2)
  • plugins/out_s3/s3.c
  • plugins/out_chronicle/chronicle.c

📝 Walkthrough

Walkthrough

Chronicle and S3 now dynamically resize scratch buffers and retry JSON serialization when configured log-key values exceed the initial capacity. Allocation failures clean up the buffer and abort extraction.

Changes

Log-key serialization

Layer / File(s) Summary
Grow-and-retry JSON serialization
plugins/out_chronicle/chronicle.c, plugins/out_s3/s3.c
Scratch-buffer state and retry loops expand capacity for oversized non-BIN/STR log-key values; allocation failures clean up and return NULL.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: edsiper

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: growing log_key buffers in out_s3 and out_chronicle to avoid dropping oversized values.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
plugins/out_chronicle/chronicle.c (1)

604-623: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Apply the required control-block brace style consistently.

  • plugins/out_chronicle/chronicle.c#L604-L623: move opening braces for the new while and if blocks onto the following line.
  • plugins/out_s3/s3.c#L3695-L3715: make the same change for the new retry-loop blocks.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/out_chronicle/chronicle.c` around lines 604 - 623, Apply the
project’s brace style to the new control blocks: in
plugins/out_chronicle/chronicle.c lines 604-623, update the while and if blocks;
in plugins/out_s3/s3.c lines 3695-3715, make the same adjustment for each new
retry-loop block. Move each opening brace onto the following line without
changing control flow.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/out_s3/s3.c`:
- Around line 3707-3715: Update the allocation-failure handling in the decoder
path around alloc_error so any failure after records have been appended cannot
return a partial payload. After destroying the decoder, free val_buf and return
NULL whenever alloc_error is set, regardless of val_offset or previously decoded
data.

---

Nitpick comments:
In `@plugins/out_chronicle/chronicle.c`:
- Around line 604-623: Apply the project’s brace style to the new control
blocks: in plugins/out_chronicle/chronicle.c lines 604-623, update the while and
if blocks; in plugins/out_s3/s3.c lines 3695-3715, make the same adjustment for
each new retry-loop block. Move each opening brace onto the following line
without changing control flow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 67c22f54-452d-47a4-a28e-2dad486fe111

📥 Commits

Reviewing files that changed from the base of the PR and between c830fb6 and f25bf78.

📒 Files selected for processing (2)
  • plugins/out_chronicle/chronicle.c
  • plugins/out_s3/s3.c

Comment thread plugins/out_s3/s3.c

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f25bf7808d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread plugins/out_s3/s3.c
Comment on lines +3709 to +3710
alloc_error = 1;
break;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Return NULL when S3 log_key growth fails

For S3 chunks using log_key, if a later non-string value needs this buffer growth and flb_realloc() fails after earlier records have already advanced val_offset, setting alloc_error only exits the decoder loop; the function then falls through and creates an SDS from the partial val_buf whenever val_offset != 0. The flush path treats that non-NULL chunk as data to upload, so the current and remaining records can be dropped while the output reports success; free the buffer and return NULL on this allocation failure instead of falling through with partial data.

Useful? React with 👍 / 👎.

vitaly-sinev and others added 2 commits July 22, 2026 09:34
The log_key extraction buffer was sized bytes + bytes/4 and never grown. A
non-string log_key value whose JSON form exceeded the remaining space made
flb_msgpack_to_json() fail; the code only broke out of the loop, so the
oversized value was silently dropped (and, before that, could be emitted
truncated).

Grow the scratch buffer and retry the conversion until the value fits, so
the value is neither truncated nor dropped. The guard on the remaining size
also avoids calling flb_msgpack_to_json() with a zero-length buffer.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: v.sinev <vit.phantom@gmail.com>
The log_key extraction buffer was sized bytes + bytes/4 and never grown. A
non-string log_key value whose JSON form exceeded the remaining space made
flb_msgpack_to_json() fail; the code only broke out of the loop, so the
oversized value was silently dropped.

Grow the scratch buffer and retry the conversion until the value fits, so
the value is neither truncated nor dropped. The guard on the remaining size
also avoids calling flb_msgpack_to_json() with a zero-length buffer.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: v.sinev <vit.phantom@gmail.com>
@vitaly-sinev
vitaly-sinev force-pushed the out-plugins-log-key-grow branch from f25bf78 to 032f864 Compare July 22, 2026 09:00
@vitaly-sinev

Copy link
Copy Markdown
Author

Good catch (both @coderabbitai and @chatgpt-codex-connector) — fixed: on alloc_error out_s3 now frees the scratch buffer and returns NULL after destroying the decoder, instead of returning a partial payload. (out_chronicle already returned NULL on growth failure.) Pushed.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@vitaly-sinev Thanks for fixing this. Returning NULL after releasing the scratch buffer and decoder prevents emitting a partial payload on allocation failure.

🐇✅


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant