From de44ae3ee6e7262302bdfa719cd195a52352e693 Mon Sep 17 00:00:00 2001 From: "Damon P. Cortesi" Date: Tue, 23 Jun 2026 14:28:35 -0700 Subject: [PATCH] out_s3: preserve $INDEX sequence state across restarts The S3 output stores the $INDEX sequence counter in a plain file under the metadata stream directory (sequence/index_metadata/seq_index_). This file is not a Chunk I/O chunk, so the metadata stream has zero registered fstore files. On (graceful) shutdown, flb_fstore_destroy() recursively deletes any stream that has no files, which removes the metadata stream and the persisted $INDEX value. On the next start the index is missing and resets to 0, so subsequent uploads reuse object keys (events_0, events_1, ...) and overwrite previously uploaded objects. This contradicts the documented behavior that $INDEX is saved in store_dir and continues from its last value after a restart on the same disk. Detach the metadata stream reference in s3_store_exit() before the store is destroyed (without deleting the directory), so the persisted index survives a restart and can be recovered by init_seq_index(). Signed-off-by: Damon P. Cortesi --- plugins/out_s3/s3_store.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/plugins/out_s3/s3_store.c b/plugins/out_s3/s3_store.c index fbaf1753c1d..d71e1fcf49d 100644 --- a/plugins/out_s3/s3_store.c +++ b/plugins/out_s3/s3_store.c @@ -353,6 +353,24 @@ int s3_store_exit(struct flb_s3 *ctx) return 0; } + /* + * Detach the metadata ("sequence") stream before tearing down the store. + * + * The $INDEX value is persisted as a plain file inside the metadata stream + * directory (sequence/index_metadata/seq_index_); it is not a Chunk I/O + * chunk, so the stream has zero registered fstore files. Because + * flb_fstore_destroy() recursively deletes any stream that has no files, the + * metadata stream (and the persisted $INDEX) would be removed on every + * graceful shutdown. Detaching the reference here (without deleting the + * directory) preserves the index on disk so it can be restored on the next + * start, which is the documented behavior of $INDEX with a persistent + * store_dir. + */ + if (ctx->stream_metadata != NULL) { + flb_fstore_stream_destroy(ctx->stream_metadata, FLB_FALSE); + ctx->stream_metadata = NULL; + } + /* release local context on non-multi upload files */ mk_list_foreach(head, &ctx->fs->streams) { fs_stream = mk_list_entry(head, struct flb_fstore_stream, _head);