Splunk HEC
Synopsis
Creates an HTTP Event Collector listener that receives events from Splunk forwarders and HEC-compatible senders over HTTP or HTTPS.
Schema
- id: <numeric>
name: <string>
description: <string>
type: splunkhec
tags: <string[]>
pipelines: <pipeline[]>
status: <boolean>
properties:
port: <numeric>
address: <string>
tokens:
- token: <string>
tenant_id: <string>
expire_date: <numeric>
max_body_size: <numeric>
enable_ack: <boolean>
reuse: <boolean>
workers: <numeric>
tls:
status: <boolean>
cert_name: <string>
key_name: <string>
passphrase: <string>
min_tls_version: <string>
max_tls_version: <string>
client_ca_name: <string>
client_auth_required: <boolean>
insecure_skip_verify: <boolean>
Configuration
The following fields are used to define the device:
Device
| Field | Required | Default | Description |
|---|---|---|---|
id | Y | - | Unique numeric identifier |
name | Y | - | Device name |
description | N | - | Optional description |
type | Y | - | Must be splunkhec |
tags | N | - | Optional tags |
pipelines | N | - | Optional pre-processor pipelines |
status | N | true | Enable/disable the device |
Connection
| Field | Required | Default | Description |
|---|---|---|---|
port | Y | - | TCP port to listen on |
address | N | "0.0.0.0" | Network address to bind |
tokens | N | - | Array of accepted HEC tokens; omit or leave empty for open access. Each entry is a plain string or an object (see Multi-Tenancy) |
max_body_size | N | 26214400 | Maximum decompressed request body size in bytes (default 25 MB) |
enable_ack | N | false | Enable indexer acknowledgement support |
reuse | N | true | Enable multi-worker mode |
workers | N | CPU count | Number of worker processes when reuse is enabled |
Multi-Tenancy
Each entry in the tokens list may be a plain string (matched as-is, with no tenant) or an object that binds the token to a tenant and an optional expiry. Both forms can be mixed in the same list.
| Field | Required | Default | Description |
|---|---|---|---|
tokens[].token | Y | The accepted token secret. Quote long numeric-looking values to preserve them exactly. | |
tokens[].tenant_id | N | - | Tenant identifier attached to records authenticated with this token. Omit for no tenant. |
tokens[].expire_date | N | never | Expiry as epoch seconds (e.g. 1924905600). The token is rejected at and after this instant. Omit for a token that never expires. |
A request presenting an expired or unknown token is rejected with 401 and no record is ingested. When a request authenticates with a token that carries a tenant_id, that tenant is written to _vmetric.event.tenant_id; the client IP always stays at _vmetric.event.request. Use _vmetric.event.tenant_id to route or isolate each customer's data downstream (see Routes).
tokens:
- token: "acme-9f3c...key"
tenant_id: "acme"
expire_date: 1924905600
- token: "globex-7a1b...key"
tenant_id: "globex"
- "legacy-plain-token"
Token changes take effect on the next collector restart.
Splunk HEC has no authentication.type — supplying tokens enables authentication. Tokens are accepted via Authorization: Splunk <token>, Authorization: Bearer <token>, a bare token, or the ?token= query parameter. A legacy token:index:sourcetype string keeps only the token portion. An expired or unknown token is rejected with HEC error code 4.
TLS
| Field | Required | Default | Description |
|---|---|---|---|
tls.status | N | false | Enable TLS encryption |
tls.cert_name | Y* | cert.pem | TLS certificate |
tls.key_name | Y* | key.pem | TLS private key |
tls.passphrase | N | - | Passphrase for an encrypted private key |
tls.min_tls_version | N | tls1.2 | Minimum accepted TLS version (tls1.0, tls1.1, tls1.2, tls1.3) |
tls.max_tls_version | N | - | Maximum accepted TLS version. When unset, the highest mutually supported version is negotiated. |
tls.client_ca_name | N | - | CA bundle used to verify client certificates (mTLS) |
tls.client_auth_required | N** | false | Require connecting clients to present a valid certificate. When false, a client certificate is verified only if one is presented. |
tls.insecure_skip_verify | N | false | Skip peer certificate verification. Use only for testing. |
* = Required when tls.status is true.
** = Requires tls.client_ca_name. If tls.client_auth_required is true or tls.client_ca_name is set and the named CA cannot be loaded, the configuration is rejected and the device fails to start.
tls.min_version is a deprecated alias for tls.min_tls_version, honored only when tls.min_tls_version is unset. Use tls.min_tls_version in new configurations.
TLS material fields (cert_name, key_name, ca_name, client_ca_name) accept any of the following:
- File name — resolved relative to the service root directory. Nested paths such as
certs/prod/server.pemare supported. - Absolute path — honored only if it resolves inside the service root. Any path that escapes the root is refused.
- Inline PEM content — used verbatim when the value contains
-----BEGIN. - Environment variable —
${ENV_VAR}. - Vault reference —
$secret{id=...}or$secret{store=...,ref=...}.
Details
The device exposes the following HTTP endpoints on the configured port:
| Endpoint | Method | Purpose |
|---|---|---|
/services/collector | POST | JSON event submission |
/services/collector/event | POST | JSON event submission (alternate) |
/services/collector/raw | POST | Raw text line submission |
/services/collector/raw/1.0 | POST | Raw text line submission (versioned) |
/services/collector/health | GET | Health check; no authentication required |
/services/collector/health/1.0 | GET | Health check (versioned); no authentication required |
/services/collector/ack | POST | Indexer acknowledgement |
The device validates the Authorization header using these schemes in order: Splunk <token>, Bearer <token>, bare token (no scheme prefix), and the ?token= query parameter as a fallback. When no tokens are configured, all requests are accepted without authentication. Health endpoints never require authentication.
Request bodies may be gzip-compressed (Content-Encoding: gzip). The max_body_size limit is enforced on the decompressed output, not on the compressed wire bytes, which prevents gzip-bomb payloads from expanding into memory unchecked.
The JSON event endpoints accept batched requests containing multiple concatenated JSON objects per body — a format that is standard HEC batch mode and is not valid single-document JSON. Each object must contain at least one of the fields event or fields at the top level; objects that fail this check return HEC error code 12.
The raw endpoint accepts plain text bodies. Each non-empty line is wrapped in a {"_raw":"..."} envelope. Per-request metadata fields (host, source, sourcetype, index) are read from query parameters and injected into every line envelope when present. When enable_ack is true, the raw endpoint also requires a channel identifier provided via the channel query parameter or the X-Splunk-Request-Channel header.
When enable_ack is true, the ACK endpoint echoes all submitted ack IDs back as confirmed (synthetic ACK). This unblocks senders that hold open connections waiting for ACK confirmation without requiring per-request state tracking. When enable_ack is false, the ACK endpoint remains registered and returns HEC error code 14 (ACK disabled) rather than a 404, matching expected Splunk behavior.
Examples
Basic
Creating a minimal HEC listener on port 8088 with open access... | |
Token Authentication
Restricting access to named tokens... | |
TLS
Enabling HTTPS with a TLS certificate and token authentication... | |
Acknowledgement
Enabling synthetic indexer acknowledgement for senders that require ACK confirmation... | |
ACK IDs are always confirmed immediately. The device does not track per-event indexing state.
High-Volume
Tuning for high-throughput ingestion with increased body size limit and worker count... | |