Skip to content

in_splunk: return Splunk HEC auth status codes#12043

Merged
edsiper merged 3 commits into
masterfrom
lecaros-fix-in-splunk-401-403
Jul 3, 2026
Merged

in_splunk: return Splunk HEC auth status codes#12043
edsiper merged 3 commits into
masterfrom
lecaros-fix-in-splunk-401-403

Conversation

@lecaros

@lecaros lecaros commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Align in_splunk HEC authentication failures with Splunk's documented HTTP status codes and JSON error bodies.

Previously, every auth failure returned 401 with plain text error: unauthorized\n. That breaks clients (e.g. Adobe Cloud onboarding prechecks) that expect Splunk's documented behavior:

  • 401 for missing or malformed Authorization headers
  • 403 for correctly formatted Authorization: Splunk <token> where the token is unknown

This change classifies auth failures in validate_auth_header_ng() and returns Splunk-compatible JSON responses from splunk_prot_handle_ng().

Case Example HTTP Body
Valid token Authorization: Splunk <configured> 200 {"text":"Success","code":0}
Missing header no Authorization 401 {"text":"Token is required","code":2}
Malformed header Authorization: <token> (no Splunk prefix) 401 {"text":"Invalid authorization","code":3}
Unknown token Authorization: Splunk <wrong> 403 {"text":"Invalid token","code":4}

Auth is enforced only when splunk_token is configured. Behavior without a configured token is unchanged.

Fixes #12036

Testing
Before we can approve your change; please submit the following in a comment:

  • Example configuration file for the change
config

service:
  flush: 1
  log_level: debug
pipeline:
  inputs:
    - name: splunk
      listen: 0.0.0.0
      port: 8088
      splunk_token: 11111111-1111-1111-1111-111111111111
  outputs:
    - name: stdout
      match: '*'

  • Debug log output from testing the change
Debug log

Fluent Bit v5.0.9
* Copyright (C) 2015-2026 The Fluent Bit Authors
* Fluent Bit is a CNCF graduated project under the Fluent organization
* https://fluentbit.io

______ _                  _    ______ _ _           _____  _____
|  ___| |                | |   | ___ (_) |         |  ___||  _  |
| |_  | |_   _  ___ _ __ | |_  | |_/ /_| |_  __   _|___ \ | |/' |
|  _| | | | | |/ _ \ '_ \| __| | ___ \ | __| \ \ / /   \ \|  /| |
| |   | | |_| |  __/ | | | |_  | |_/ / | |_   \ V //\__/ /\ |_/ /
\_|   |_|\__,_|\___|_| |_|\__| \____/|_|\__|   \_/ \____(_)\___/


[2026/07/03 15:09:17.878] [ info] Configuration:
[2026/07/03 15:09:17.878] [ info]  flush time     | 1.000000 seconds
[2026/07/03 15:09:17.878] [ info]  grace          | 5 seconds
[2026/07/03 15:09:17.878] [ info]  daemon         | 0
[2026/07/03 15:09:17.878] [ info] ___________
[2026/07/03 15:09:17.878] [ info]  inputs:
[2026/07/03 15:09:17.878] [ info]      splunk
[2026/07/03 15:09:17.878] [ info] ___________
[2026/07/03 15:09:17.878] [ info]  filters:
[2026/07/03 15:09:17.878] [ info] ___________
[2026/07/03 15:09:17.878] [ info]  outputs:
[2026/07/03 15:09:17.878] [ info]      stdout.0
[2026/07/03 15:09:17.878] [ info] ___________
[2026/07/03 15:09:17.878] [ info]  collectors:
[2026/07/03 15:09:17.879] [ info] [fluent bit] version=5.0.9, commit=d0612246fe, pid=19652
[2026/07/03 15:09:17.879] [debug] [engine] coroutine stack size: 24576 bytes (24.0K)
[2026/07/03 15:09:17.879] [ info] [storage] ver=1.5.4, type=memory, sync=normal, checksum=off, max_chunks_up=128
[2026/07/03 15:09:17.879] [ info] [simd    ] disabled
[2026/07/03 15:09:17.879] [ info] [cmetrics] version=2.1.5
[2026/07/03 15:09:17.879] [ info] [ctraces ] version=0.7.1
[2026/07/03 15:09:17.879] [ info] [input:splunk:splunk.0] initializing
[2026/07/03 15:09:17.879] [ info] [input:splunk:splunk.0] storage_strategy='memory' (memory only)
[2026/07/03 15:09:17.879] [debug] [splunk:splunk.0] created event channels: read=21 write=22
[2026/07/03 15:09:17.879] [debug] [downstream] listening on 0.0.0.0:8088
[2026/07/03 15:09:17.879] [ info] [input:splunk:splunk.0] listening on 0.0.0.0:8088 with 1 worker
[2026/07/03 15:09:17.879] [debug] [stdout:stdout.0] created event channels: read=24 write=25
[2026/07/03 15:09:17.879] [ info] [sp] stream processor started
[2026/07/03 15:09:17.879] [ info] [engine] Shutdown Grace Period=5, Shutdown Input Grace Period=2
[2026/07/03 15:09:17.880] [ info] [output:stdout:stdout.0] worker #0 started
[2026/07/03 15:09:37.301] [debug] [input:splunk:splunk.0] Mark as unknown type for ingested payloads
[2026/07/03 15:09:37.580] [debug] [task] created task=0x7fa08802f0f0 id=0 OK
[2026/07/03 15:09:37.580] [debug] [output:stdout:stdout.0] task_id=0 assigned to thread #0
[0] splunk.0: [[1783091377.301386910, {"hec_token"=>"Splunk 11111111-1111-1111-1111-111111111111"}], {"event"=>"x"}]
[2026/07/03 15:09:37.580] [debug] [out flush] cb_destroy coro_id=0
[2026/07/03 15:09:37.580] [debug] [task] destroy task=0x7fa08802f0f0 (task_id=0)
[2026/07/03 15:09:46.390] [ warn] [input:splunk:splunk.0] wrong credentials in request headers
[2026/07/03 15:10:00.342] [ warn] [input:splunk:splunk.0] invalid authorization in request headers
^C[2026/07/03 15:10:10] [engine] caught signal (SIGINT)
[2026/07/03 15:10:10.847] [ warn] [engine] service will shutdown in max 5 seconds
[2026/07/03 15:10:10.847] [ info] [engine] pausing all inputs..
[2026/07/03 15:10:11.580] [ info] [engine] service has stopped (0 pending tasks)
[2026/07/03 15:10:11.580] [ info] [output:stdout:stdout.0] thread worker #0 stopping...
[2026/07/03 15:10:11.580] [ info] [output:stdout:stdout.0] thread worker #0 stopped

  • Attached Valgrind output that shows no leaks or memory corruption was found
valgrind


valgrind --leak-check=yes $FBIT_HOME/fluent-bit -c fluent-bit.yml
==94070== Memcheck, a memory error detector
==94070== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==94070== Using Valgrind-3.24.0 and LibVEX; rerun with -h for copyright info
==94070== Command: /home/lecaros/fluent-bit/build/bin/fluent-bit -c fluent-bit.yml
==94070==
Fluent Bit v5.0.9
* Copyright (C) 2015-2026 The Fluent Bit Authors
* Fluent Bit is a CNCF graduated project under the Fluent organization
* https://fluentbit.io

______ _                  _    ______ _ _           _____  _____
|  ___| |                | |   | ___ (_) |         |  ___||  _  |
| |_  | |_   _  ___ _ __ | |_  | |_/ /_| |_  __   _|___ \ | |/' |
|  _| | | | | |/ _ \ '_ \| __| | ___ \ | __| \ \ / /   \ \|  /| |
| |   | | |_| |  __/ | | | |_  | |_/ / | |_   \ V //\__/ /\ |_/ /
\_|   |_|\__,_|\___|_| |_|\__| \____/|_|\__|   \_/ \____(_)\___/


[2026/07/03 17:51:30.144] [ info] Configuration:
[2026/07/03 17:51:30.174] [ info]  flush time     | 1.000000 seconds
[2026/07/03 17:51:30.182] [ info]  grace          | 5 seconds
[2026/07/03 17:51:30.183] [ info]  daemon         | 0
[2026/07/03 17:51:30.183] [ info] ___________
[2026/07/03 17:51:30.184] [ info]  inputs:
[2026/07/03 17:51:30.184] [ info]      splunk
[2026/07/03 17:51:30.185] [ info] ___________
[2026/07/03 17:51:30.185] [ info]  filters:
[2026/07/03 17:51:30.186] [ info] ___________
[2026/07/03 17:51:30.186] [ info]  outputs:
[2026/07/03 17:51:30.187] [ info]      stdout.0
[2026/07/03 17:51:30.187] [ info] ___________
[2026/07/03 17:51:30.188] [ info]  collectors:
[2026/07/03 17:51:30.356] [ info] [fluent bit] version=5.0.9, commit=d0612246fe, pid=94070
[2026/07/03 17:51:30.371] [debug] [engine] coroutine stack size: 24576 bytes (24.0K)
[2026/07/03 17:51:30.397] [ info] [storage] ver=1.5.4, type=memory, sync=normal, checksum=off, max_chunks_up=128
[2026/07/03 17:51:30.398] [ info] [simd    ] SSE2
[2026/07/03 17:51:30.399] [ info] [cmetrics] version=2.1.5
[2026/07/03 17:51:30.419] [ info] [ctraces ] version=0.7.1
[2026/07/03 17:51:30.463] [ info] [input:splunk:splunk.0] initializing
[2026/07/03 17:51:30.464] [ info] [input:splunk:splunk.0] storage_strategy='memory' (memory only)
[2026/07/03 17:51:30.467] [debug] [splunk:splunk.0] created event channels: read=21 write=22
[2026/07/03 17:51:30.526] [debug] [downstream] listening on 0.0.0.0:8088
[2026/07/03 17:51:30.529] [ info] [input:splunk:splunk.0] listening on 0.0.0.0:8088 with 1 worker
[2026/07/03 17:51:30.539] [debug] [stdout:stdout.0] created event channels: read=24 write=25
[2026/07/03 17:51:30.711] [ info] [sp] stream processor started
[2026/07/03 17:51:30.717] [ info] [engine] Shutdown Grace Period=5, Shutdown Input Grace Period=2
[2026/07/03 17:51:30.757] [ info] [output:stdout:stdout.0] worker #0 started
[2026/07/03 17:52:07.830] [debug] [input:splunk:splunk.0] Mark as unknown type for ingested payloads
[2026/07/03 17:52:08.696] [debug] [task] created task=0x58af1b0 id=0 OK
[0] splunk.0: [[1783101127.846571359, {"hec_token"=>"Splunk 11111111-1111-1111-1111-111111111111"}], {"event"=>"x"}]
[2026/07/03 17:52:08.701] [debug] [output:stdout:stdout.0] task_id=0 assigned to thread #0
[2026/07/03 17:52:08.728] [debug] [out flush] cb_destroy coro_id=0
[2026/07/03 17:52:08.743] [debug] [task] destroy task=0x58af1b0 (task_id=0)
[2026/07/03 17:52:14.227] [ warn] [input:splunk:splunk.0] wrong credentials in request headers
[2026/07/03 17:52:21.680] [ warn] [input:splunk:splunk.0] invalid authorization in request headers
^C[2026/07/03 17:52:23] [engine] caught signal (SIGINT)
[2026/07/03 17:52:23.962] [ warn] [engine] service will shutdown in max 5 seconds
[2026/07/03 17:52:23.963] [ info] [engine] pausing all inputs..
[2026/07/03 17:52:24.686] [ info] [engine] service has stopped (0 pending tasks)
[2026/07/03 17:52:24.691] [ info] [output:stdout:stdout.0] thread worker #0 stopping...
[2026/07/03 17:52:24.701] [ info] [output:stdout:stdout.0] thread worker #0 stopped
==94070==
==94070== HEAP SUMMARY:
==94070==     in use at exit: 0 bytes in 0 blocks
==94070==   total heap usage: 2,875 allocs, 2,875 frees, 3,976,457 bytes allocated
==94070==
==94070== All heap blocks were freed -- no leaks are possible
==94070==
==94070== For lists of detected and suppressed errors, rerun with: -s
==94070== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Backporting

  • Backport to latest stable release.

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.

Summary by CodeRabbit

  • New Features
    • Improved Splunk HEC authentication responses with HEC-style JSON errors and clearer status codes: missing credentials (401, code 2), invalid authorization (401, code 3), and invalid tokens (403, code 4).
    • Added more accurate HTTP reason phrase mapping for forbidden responses (403 → “Forbidden”).
  • Tests
    • Added integration scenario coverage for HEC authentication variants (valid token, invalid token, malformed header, missing authorization) and asserts expected HTTP status codes and response bodies, using a new Splunk HEC token auth test configuration.

Signed-off-by: lecaros <lecaros@chronosphere.io>
@coderabbitai

coderabbitai Bot commented Jul 3, 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: a2bcba1b-f5ac-466e-9e37-dc08cb45919f

📥 Commits

Reviewing files that changed from the base of the PR and between 35c0fff and 19e42eb.

📒 Files selected for processing (1)
  • tests/integration/scenarios/in_splunk/config/splunk_http1_token_auth.yaml

📝 Walkthrough

Walkthrough

The Splunk HEC input plugin now returns distinct JSON error responses for missing credentials, malformed authorization headers, and unknown tokens, including 401 and 403 status codes. Integration coverage was added for these auth cases.

Changes

Splunk HEC auth response differentiation

Layer / File(s) Summary
Auth result macros
plugins/in_splunk/splunk_prot.h
SPLUNK_AUTH_UNAUTHORIZED is replaced by SPLUNK_AUTH_INVALID_AUTHORIZATION, and SPLUNK_AUTH_INVALID_TOKEN is added.
Auth validation and response logic
plugins/in_splunk/splunk_prot.c
send_json_message_response_ng maps 403 to Forbidden; validate_auth_header_ng separates invalid token from invalid authorization; splunk_prot_handle_ng emits JSON responses for missing credentials, invalid authorization, and invalid token.
Integration test coverage
tests/integration/scenarios/in_splunk/config/splunk_http1_token_auth.yaml, tests/integration/scenarios/in_splunk/tests/test_in_splunk_001.py
A token-auth scenario config and a parametrized integration test assert the expected status code and response body for each HEC auth header variant.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested reviewers: edsiper, fujimotos, koleini

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: Splunk HEC auth status codes.
Linked Issues check ✅ Passed The changes match the linked issue by returning 401/403 with Splunk-style error codes for missing, malformed, and unknown tokens.
Out of Scope Changes check ✅ Passed The added config and tests support the auth response change and do not introduce unrelated scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch lecaros-fix-in-splunk-401-403

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.

@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: d0612246fe

ℹ️ 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 tests/integration/scenarios/in_splunk/tests/test_in_splunk_001.py
Signed-off-by: lecaros <lecaros@chronosphere.io>
Signed-off-by: lecaros <lecaros@chronosphere.io>
@edsiper edsiper added this to the Fluent Bit v5.0.9 milestone Jul 3, 2026
@edsiper edsiper merged commit eacb063 into master Jul 3, 2026
87 of 90 checks passed
@edsiper edsiper deleted the lecaros-fix-in-splunk-401-403 branch July 3, 2026 22:35
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.

in_splunk: unknown token returns HTTP 401 instead of Splunk's 403 "Invalid token" (code 4)

2 participants