Elasticsearch
Synopsis
Creates an Elasticsearch target that sends data using the Bulk API. Supports multiple endpoints, field normalization, customizable batch sizing, and automatic load balancing across Elasticsearch nodes.
Schema
- name: <string>
description: <string>
type: elastic
status: <boolean>
pipelines: <pipeline[]>
properties:
version: <numeric>
index: <string>
max_payload_size_kb: <numeric>
batch_size: <numeric>
timeout: <numeric>
insecure_skip_verify: <boolean>
ca_name: <string>
server_name: <string>
cert_name: <string>
key_name: <string>
passphrase: <string>
min_tls_version: <string>
max_tls_version: <string>
use_compression: <boolean>
write_action: <string>
filter_path: <string>
pipeline: <string>
field_format: <string>
endpoints:
- endpoint: <string>
username: <string>
password: <string>
debug:
status: <boolean>
dont_send_logs: <boolean>
Configuration
The following are the fields used to define the target:
| Field | Required | Default | Description |
|---|---|---|---|
name | Y | - | Target name |
description | N | - | Optional description |
type | Y | - | Must be elastic |
pipelines | N | - | Optional post-processor pipelines |
status | N | true | Enable/disable the target |
Elasticsearch
| Field | Required | Default | Description |
|---|---|---|---|
version | N | auto | Accepted but not applied. The value is stored and never read, so no version detection or version-specific behavior follows from it |
index | Y | - | Default Elasticsearch index name |
max_payload_size_kb | N | 4096 | Maximum bulk request size in KB |
batch_size | N | 10000 | Maximum number of events per batch |
timeout | N | 30 | Connection timeout in seconds |
use_compression | N | true | Enable GZIP compression |
write_action | N | create | Bulk API action (index, create, update, delete) |
filter_path | N | errors,items.*.error,items.*._index,items.*.status | Response filter path |
pipeline | N | - | Ingest pipeline name |
field_format | N | - | Data normalization format. See applicable Normalization section |
Endpoint
| Field | Required | Default | Description |
|---|---|---|---|
endpoint | Y | - | Elasticsearch URL (automatically appends /_bulk if not present) |
username | N | - | Basic auth username |
password | N | - | Basic auth password |
TLS
TLS is engaged by the endpoint URL scheme: an https:// endpoint enables it, an http:// endpoint does not. There is no status field. The fields below are top-level, at the root of properties.
The web interface exposes only insecure_skip_verify for these targets. Every other field below — the CA bundle, the client certificate and key, the SNI override and the version bounds — has to be set in the YAML configuration or through the API; there is no form control for it.
| Field | Required | Default | Description |
|---|---|---|---|
insecure_skip_verify | N | false | Skip server certificate verification. Use only for testing. |
ca_name | N | - | CA bundle used to verify the server certificate. When unset, the host trust store is used; when set, it replaces the host trust store rather than adding to it. |
server_name | N | - | SNI hostname override for the TLS handshake |
cert_name | N* | - | Client certificate for mutual TLS |
key_name | N* | - | Client private key for mutual TLS |
passphrase | N | - | Passphrase for an encrypted private key |
min_tls_version | N | tls1.2 | Minimum accepted TLS version (tls1.0, tls1.1, tls1.2, tls1.3) |
max_tls_version | N | tls1.3 | Maximum accepted TLS version (tls1.0, tls1.1, tls1.2, tls1.3) |
* = Mutual TLS requires both cert_name and key_name. Setting only one is a configuration error.
A nested tls: block is also accepted, and a non-empty one replaces the flat shape rather than merging with it: the sender reads the block and ignores every flat key, including options the block leaves out. Use one shape or the other, never a mixture.
insecure_skip_verify is the single exception. It is read from the nested block when present and otherwise falls back to the root, so a target carrying a hand-written tls: block keeps the skip-verify its form wrote. Only an absent nested value falls through — a nested false is an explicit statement and overrides a root true.
There is no tls.status: TLS is off when the whole block is absent, and a status key inside the block is not read.
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=...}.
Scheduling
See Scheduling and Pool Behavior for interval and cron fields shared by all targets.
Debug Options
| Field | Required | Default | Description |
|---|---|---|---|
debug.status | N | false | Enable debug logging |
debug.dont_send_logs | N | false | Process logs but don't send to target (testing) |
Details
The target supports multiple endpoints, authentication, compression, and ingest pipelines. Data is batched for efficient delivery and can be automatically routed to different indices.
URLs are automatically appended with /_bulk if the suffix is not present. Events are batched until either the batch size or payload size limit is reached.
For load balancing, events are sent to randomly selected endpoints. If an endpoint fails, the next endpoint in the randomized list is tried until successful delivery or all endpoints fail.
Each event is automatically enriched with a timestamp in RFC3339 format based on the log's epoch time. You can route events to different indices by setting the index field in a pipeline processor.
Long timeout values may lead to connection pooling issues and increased resource consumption.
Setting max_payload_size_kb too high might cause memory pressure and can exceed Elasticsearch's http.max_content_length setting (default 100MB).
Load Balancing and Failover
When multiple endpoints are configured, the target uses randomized load balancing. For each batch:
- Endpoints are randomly shuffled
- The batch is sent to the first endpoint
- If it fails, the next endpoint in the shuffled list is tried
- This continues until successful delivery or all endpoints fail
If only some endpoints fail but delivery eventually succeeds, the batch is cleared and a partial error is logged. If all endpoints fail, the batch is retained for retry and a complete failure error is returned.
JSON Message Handling
The target intelligently handles messages that are already in JSON format:
- If a message contains the text
@timestampanywhere, or is ECS-normalized, it's treated as a structured JSON document - The JSON is parsed and sent as-is to Elasticsearch
- If parsing fails, the record is not sent. Delivery fails with
failed to parse JSON messageand the payload is retried. There is no plain-text fallback for these records - Any other message is wrapped into a JSON document with its text, a timestamp, and the destination index
This allows you to send both structured and unstructured logs through the same target, as long as plain text does not mention @timestamp.
Dynamic Index Routing
Route events to different indices using pipeline processors by setting the index field:
pipelines:
- name: route_by_type
processors:
- set:
field: index
value: "error-logs"
if: "level == 'error'"
- set:
field: index
value: "metrics"
if: "type == 'metric'"
This allows flexible routing without creating multiple target configurations.
Bulk API Error Handling
The target parses the bulk API response to detect individual document errors:
- Uses
filter_pathto reduce response size and focus on error details - Extracts error type, reason, and HTTP status for failed documents
- Returns detailed error messages indicating which documents failed and why
Common errors include:
- Document version conflicts (for
createaction) - Mapping errors (field type mismatches)
- Index not found or closed
- Pipeline failures (when using ingest pipelines)
Write Actions
The write_action field determines how documents are indexed:
create(default): Only index if document doesn't exist. Fails on duplicates.index: Index or replace existing document. Always succeeds unless there's a system error.update: Update existing document. Fails if document doesn't exist.delete: Remove document. Use carefully.
Response Filtering
The filter_path parameter filters the bulk API response to reduce network overhead:
errors: Boolean indicating if any operations faileditems.*.error: Error details for failed operationsitems.*._index: Index name for each operationitems.*.status: HTTP status code for each operation
For high-volume scenarios, this filtering significantly reduces response size and parsing overhead.
Field Normalization
The field_format property allows normalizing log data to standard formats:
ecs- Elastic Common Schema
Field normalization is applied before the logs are sent to Elasticsearch, ensuring consistent indexing and search capabilities. ECS normalization maps common fields to Elasticsearch's standard schema for improved compatibility with Kibana dashboards and detection rules.
Compression
Compression is enabled by default and uses gzip to reduce network bandwidth. This adds minimal CPU overhead but can significantly improve throughput for high-volume scenarios. Disable compression only if you have bandwidth to spare and want to reduce CPU usage.
Examples
Basic
Simple Elasticsearch output with a single endpoint... | |
Secure
Secure configuration with authentication and TLS... | |
In production environments, setting insecure_skip_verify to true is not recommended.
Ingest Pipeline
Send data through an ingest pipeline for server-side processing... | |
High-Volume
Optimized for high-volume data ingestion with load balancing... | |
Field Normalization
Using ECS field normalization for enhanced compatibility with Elastic Stack... | |
Index Action
Using index action to allow document updates and overwrites... | |
Minimal Response
Optimize for minimal response size by filtering to only errors... | |
Performance Tuning
Batch Size vs Payload Size
Events are batched until either limit is reached:
batch_size: Number of events per batchmax_payload_size_kb: Total size in kilobytes
Tune these based on your average event size:
- Small events (<1KB>): Increase
batch_size, keep defaultmax_payload_size_kb - Large events (>10KB): Keep default
batch_size, increasemax_payload_size_kb - Mixed sizes: Monitor both limits and adjust based on actual batch sizes
Timeout
Setting appropriate timeouts helps balance reliability and performance:
- Short timeouts (10-30s): Fail fast, better for real-time scenarios
- Long timeouts (60s+): More tolerant of network issues, but may cause connection pooling problems
Compression
Enable compression (default) for high-volume scenarios to reduce network bandwidth. Disable only if CPU is constrained and network bandwidth is abundant.
Filter Path
The default filter_path provides detailed error information while minimizing response size. For even better performance in high-volume scenarios with low error rates, use filter_path: "errors" to only return the error flag.
Troubleshooting
This section covers the errors you are most likely to see with the elastic target, what causes each one, and how to fix it. The same implementation serves the amazonopensearch and elasticsecurity targets, documented on their own pages as Amazon OpenSearch and Elastic Security, so everything here applies to them as well. Where Amazon OpenSearch differs, because it signs requests with AWS IAM instead of sending a user and password, the entry says so.
Where to look:
- Director logs. Target errors are tagged with the target name and carry
"Section":"SenderPool". The part afterReason:or after the last colon is the actual cause. Everything up tofrom Elastic:is written by Director, and what follows it is the cluster's own answer. - The target's connection status in the web interface. It shows the same reason as the log line.
See Target Delivery Errors for how Director logs and retries target failures.
Which permission or setting is missing?
No permission is checked while the target starts. Director resolves the credentials, builds one HTTP client per endpoint, and reports the target as connected without calling the cluster once. The first proof that a credential or a privilege works is the first batch, so permission problems always arrive as delivery errors and never as startup errors. Match the error you see against this table.
| Error text | What it needs | Must be granted on |
|---|---|---|
received status code 401 from Elastic: with a security_exception body (typical) | username and password both filled in, for a cluster user that is enabled | Every entry under endpoints. Credentials are per endpoint, not per target |
received status code 403 from Elastic: naming indices:data/write/bulk (typical) | The index privilege create_doc for the default write_action: create, or index, write or create for write_action: index | Every index or data stream the target writes to, including every value a pipeline puts in the index field |
A per-item failure whose type is typically index_not_found_exception | The auto_configure or create_index index privilege, and a cluster action.auto_create_index setting that allows the name | Only when the index or data stream does not already exist. The target never creates one |
A per-item failure naming the id in pipeline (typical) | The ingest pipeline has to exist on the cluster. No extra privilege is needed for it | Only when pipeline is set |
received status code 403 from Elastic: naming es:ESHttpPost (typical) | The IAM action es:ESHttpPost | arn:aws:es:<region>:<account>:domain/<domain name>/*, for the identity the target signs with, on amazonopensearch with use_iam: true |
failed to sign request: failed to retrieve AWS credentials: | Both key and secret, or an instance or task role on the Director host | amazonopensearch with use_iam: true |
username and password are the only user credentials the target sends. Elastic API keys, Cloud IDs and bearer tokens are not accepted, so basic authentication, or AWS IAM on Amazon OpenSearch, are the two ways to authenticate. No cluster-level privilege is required. The target only posts to /_bulk and never reads cluster or version information, so monitor, manage and read actions can all be left out. On Amazon OpenSearch with fine-grained access control, the IAM action alone is not enough either: the domain access policy has to allow the same principal, and the IAM identity has to be mapped to an OpenSearch role that may write to the index.
OpenSearch Serverless collections are not supported. Requests are always signed for the es service, and a Serverless collection expects aoss, so it refuses every batch with a 403 whose body typically complains about the service name. Send to a managed OpenSearch domain instead.
"received status code 401 from Elastic"
[Error] [director] [target-<target id>] [elastic_output] Sender worker 2 execute() failed for elastic_output: target broken: failed to finalize target cache: endpoint https://elasticsearch.example.com:9200/_bulk: received status code 401 from Elastic: ...; all endpoints failed
Cause: the cluster rejected the credentials. The body after from Elastic: is the cluster's own answer, and for a 401 it typically carries a security_exception with wording like unable to authenticate user, or missing authentication credentials for REST request. The second wording is the trap: the authentication header is only sent when username and password both hold a value, so leaving either one empty sends the batch anonymously and the cluster reports credentials as missing even though a user is configured.
Fix: set both fields on every entry under endpoints, and confirm the user is enabled on the cluster. If a value comes from ${VAR} or $secret{...}, check that it resolves to something non-empty. On Amazon OpenSearch with use_iam: false, the internal user has to exist in the domain's own user database. No data is lost: a 401 is never given up on, so the payload stays queued and is retried every few seconds until the credentials work.
"received status code 403 from Elastic"
[Error] [director] [target-<target id>] [elastic_output] Sender worker 1 execute() failed for elastic_output: target broken: failed to finalize target cache: endpoint https://elasticsearch.example.com:9200/_bulk: received status code 403 from Elastic: ...; all endpoints failed
Cause: the credentials were accepted but the write was not allowed. The body tells you which of two forms you have.
- On Elasticsearch, it typically names a
security_exception, the actionindices:data/write/bulk, the user, and the index it refused, along with the privileges that would have granted it. - On Amazon OpenSearch with IAM, it typically names the signing identity and
is not authorized to perform: es:ESHttpPost. A body that complains about the signature, the region, or an expired token means the request was signed wrongly rather than blocked by a policy.
Fix:
- On Elasticsearch, grant the index privilege from the table above on every index pattern the target writes to, then wait for the next retry.
- On Amazon OpenSearch, grant
es:ESHttpPoston the domain ARN, allow the same principal in the domain access policy, and map the IAM identity to a writing role if fine-grained access control is on. - For a signature complaint, check that
secretis the one that belongs tokey, and thatregionis the domain's own region. - For an expired token, replace
session. A signature that worked yesterday and fails today typically means the Director host clock has drifted, so check NTP on the host.
No data is lost, and the batch is retried until the permission is in place.
"bulk operation had errors" with a document the index refuses
The cluster can accept the request and still refuse individual documents. Those failures are reported per item, one segment per document, typically like this:
[Error] [director] [target-<target id>] [elastic_output] Sender worker 1 Finalize failed on flush for target "elastic_output": endpoint https://elasticsearch.example.com:9200/_bulk: record rejected by target: bulk operation had errors: item 0 (create on app-logs): status 400, type=..., reason=...
Cause: each segment gives the document's position in the batch, the action and index it was sent to, the status the cluster gave it, and the cluster's own type and reason. With status 400 the type is typically document_parsing_exception, mapper_parsing_exception or strict_dynamic_mapping_exception, and the reason typically names the field and the mapped type it could not be parsed into. An illegal_argument_exception covers the rest: a data stream that only accepts create, an ingest pipeline that does not exist, or a field-count limit that has been reached.
Fix: read the type and reason of the first item, then fix the source of the mismatch.
- Correct the index mapping or template, or normalize the field in a Director pipeline with
convert,remove, orfield_format: ecs. - Set
write_action: createwhen the destination is a data stream. A data stream refusesindex. - Create the ingest pipeline named in
pipelineon the cluster, or remove the setting. - Check
write_actionfor typos. The value is not validated, so an unknown action makes the cluster refuse the whole batch with a 400.
This is where data is lost. The rejection is treated as deterministic, so the payload is delivered four times and then given up on, logged as dropping <payload> for target "elastic_output" after 4 rejected flush attempts. The whole payload goes, not only the refused documents, so records the index would have accepted are lost with them. Fix the mapping before the fourth delivery, or the batch is gone.
Expect duplicates as well. Chunks that were accepted earlier in the same flush are sent again on each of the four deliveries, and with create and no document id the cluster generates a new id every time.
"single event at index ... exceeds hard limit", or status 413
Two size limits produce two different errors. One document larger than max_payload_size_kb is refused before the cluster is contacted:
[Error] [director] [target-<target id>] [elastic_output] Sender worker 4 Finalize failed on flush for target "elastic_output": endpoint https://elasticsearch.example.com:9200/_bulk: record rejected by target: single event at index 37 size 4318221 bytes exceeds hard limit of 4096 KB
A batch that is too large for the cluster is refused by the cluster, typically with an empty body:
[Error] [director] [target-<target id>] [elastic_output] Sender worker 4 Finalize failed on flush for target "elastic_output": endpoint https://elasticsearch.example.com:9200/_bulk: record rejected by target: received status code 413 from Elastic:
Cause: batches are cut into chunks at 90 percent of max_payload_size_kb, measured before compression, so the default of 4096 produces chunks of about 3.6 MB. A single document above the full max_payload_size_kb fits into no chunk at all and gives the first error. A 413 means the chunk was still too large for the cluster's http.max_content_length, or for a proxy in front of it.
Fix: for the first error, raise max_payload_size_kb above the size the message reports, or trim the record in a pipeline before it reaches the target. For the 413, lower max_payload_size_kb under the limit the cluster or the proxy enforces, or raise that limit. Both wrap the same rejection as the entry above, so both lose the payload after four deliveries. Treat a 413 as urgent.
"received status code 429 from Elastic", or per-item throttling
[Error] [director] [target-<target id>] [elastic_output] Sender worker 6 execute() failed for elastic_output: target broken: failed to finalize target cache: endpoint https://elasticsearch.example.com:9200/_bulk: received status code 429 from Elastic: ...; all endpoints failed
Cause: the cluster is pushing back on the write rate. The body typically names an es_rejected_execution_exception. The same back-pressure can also arrive per document, as status 429 segments inside a bulk operation had errors message, when only part of the batch was refused.
Fix: send less per request and spread the requests out. Lower batch_size, lower max_payload_size_kb, or give the target an interval or cron so it flushes on a schedule instead of after every payload. See Scheduling and Pool Behavior. Adding indexing capacity on the cluster side addresses the cause rather than the symptom.
No data is lost, and the batch is retried until the cluster accepts it. The target has no rate limiting of its own and does not read a Retry-After header, so a throttled batch comes back every few seconds. When only some documents in a chunk were refused, the whole chunk is sent again, so the accepted ones are indexed twice.
"no such host", "connection refused", or a certificate error
A transport failure is reported with the request URL and then the network stack's own message. A name that does not resolve typically reads like this:
[Error] [director] [target-<target id>] [elastic_output] Sender worker 3 execute() failed for elastic_output: target broken: failed to finalize target cache: endpoint https://elasticsearch.example.com:9200/_bulk: Post "https://elasticsearch.example.com:9200/_bulk?filter_path=...": dial tcp: lookup elasticsearch.example.com: no such host; all endpoints failed
Cause: the tail of the line says which step failed. The wording comes from the network stack, so it varies, but these are the ones you will meet.
| Text in the tail | What it means | What to change |
|---|---|---|
no such host | The endpoint hostname does not resolve from the Director host | Fix the name in endpoint, or the host's DNS |
connection refused or i/o timeout | Wrong port, a firewall in the way, or the node is down | Open the port, or correct endpoint |
context deadline exceeded | The cluster did not answer within timeout, 30 seconds by default | Raise timeout, or lower batch_size so each request is smaller |
x509: certificate signed by unknown authority | The cluster presents a certificate from a private CA | Set ca_name to that CA. Use insecure_skip_verify: true only while testing |
certificate is valid for another name | The certificate does not cover the name or address in endpoint | Set server_name to the name on the certificate |
tls: bad certificate | The cluster wants a client certificate | Set cert_name and key_name, and passphrase if the key is encrypted |
server gave HTTP response to HTTPS client | endpoint uses https:// against a plain HTTP port | Correct the scheme or the port |
proxyconnect tcp: | The proxy in HTTPS_PROXY refused the connection or could not be reached | Fix the proxy, or add the host to NO_PROXY for the Director service |
first path segment in URL cannot contain colon | endpoint has no scheme, for example elasticsearch.example.com:9200 | Write the full URL, https://elasticsearch.example.com:9200 |
A 404 belongs here too. /_bulk is appended to whatever endpoint holds, so a Kibana or OpenSearch Dashboards URL produces a 404 whose body typically says that no handler was found for the path. Point endpoint at the search REST root, not at the user interface in front of it.
Fix: correct the setting named above, then wait for the next attempt. No data is lost while this lasts. When several endpoints are configured, each reason is listed as its own endpoint <url>: <reason> segment and the line ends with all endpoints failed, so read the segments separately. They can fail for different reasons.
"partial endpoint failed"
[Warning] [director] [target-<target id>] [elastic_output] One or more endpoints have failed during finalization of elastic_output target logs. Error: endpoint https://elasticsearch.example.com:9200/_bulk: Post "https://elasticsearch.example.com:9200/_bulk?filter_path=...": dial tcp 10.0.1.5:9200: connect: connection refused
partial endpoint failed
Cause: one endpoint failed and another accepted the data. Endpoints are shuffled for each batch and tried in that order, so this is the normal face of a single unhealthy node. The message is a warning, not an error, and it names the endpoint that failed.
Fix: check the named node. Nothing needs to change in the target, and the warning stops when the node recovers or is removed from endpoints. The data was delivered. When an endpoint fails part way through a batch, only the part that was not sent yet goes to the next endpoint, so failover does not duplicate documents across endpoints.
"failed to parse bulk response"
[Error] [director] [target-<target id>] [elastic_output] Sender worker 3 execute() failed for elastic_output: target broken: failed to finalize target cache: endpoint https://elasticsearch.example.com:9200/_bulk: failed to parse bulk response: ...; all endpoints failed
Cause: Director reads a bounded amount of the bulk response, at least 1 MB and more for large chunks. When every document in a chunk is refused and the cluster's reasons are long, the answer outgrows that bound and the copy that is parsed ends mid-document. The log can then only report that the response did not parse. It cannot show the per-item reasons, because they sit past the point where the copy ends. This is a limit of how much of the answer the log can carry, not a fault on the cluster.
Fix: get the reason from the cluster instead.
- Lower
batch_size, to500for example. Fewer documents per chunk means fewer reasons in the answer, and the next attempt usually reports them as a normalbulk operation had errorsmessage. - Send a handful of the same records to the same index by hand, with the same
write_actionandpipeline, and read the per-item reason the cluster returns. - Compare the fields your pipeline emits against the current mapping of the destination index. A mapping or template change is the usual trigger for a chunk where every document fails at once.
- Look up the same index and period in the cluster's own logs.
The same message also appears when the answer was never a bulk response: a proxy or captive portal replying 200 with an HTML page, or a port that belongs to another service. Confirm that endpoint is the search REST root. No data is lost, but nothing gets through either. The batch is retried indefinitely, because the per-item rejections that would have capped it at four deliveries are never read, so treat this one as urgent.
"failed to parse JSON message"
[Error] [director] [target-<target id>] [elastic_output] Sender worker 2 execute() failed for elastic_output: target broken: failed to send log record: failed to parse JSON message: ...
Cause: a record is parsed as a JSON document when it is ECS-normalized, or when its text contains @timestamp anywhere at all. A plain line that merely mentions @timestamp, a truncated JSON object, or a JSON array takes the same path and fails to parse. Records that do not contain that text are wrapped into a JSON document automatically, so they never reach this error.
Fix: make the pipeline emit a JSON object for those records, or rewrite the text so it no longer contains @timestamp. No data is lost and nothing is dropped, but the record is never accepted either. It is retried every few seconds and holds up everything queued behind it, so treat it as urgent.
Configuration errors that stop the target from starting
These reach you as ValidateConfig failed for target "elastic_output": ..., or as Failed to reinitialize target "elastic_output" (attempt N). Reason: ..., and they repeat until the configuration changes. Nothing is sent while any of them lasts, and incoming data waits in the queue.
| Reason text | Fix |
|---|---|
no valid Elasticsearch endpoints configured | Give at least one entry under endpoints an endpoint URL |
batch_size must be greater than 0 or max_payload_size_kb must be greater than 0 | Remove the setting to use its default, 10000 events and 4096 KB, or set a positive value |
region is required when use_iam is enabled for endpoint: | On amazonopensearch, set region on that endpoint, or set use_iam: false to use a user and password |
failed to resolve password: or failed to resolve access key: | The ${VAR} or $secret{...} reference could not be resolved. Export the variable for the Director service itself, or correct the store name and the reference |
failed to build TLS config: | The rest of the line names the file or the setting. Custom TLS material has to be inline PEM, or a path under the service root, and cert_name and key_name are only accepted together |
The target is connected but nothing arrives in the index
Nothing fails here, so there is no error to search for. Check the following in order.
-
debug.dont_send_logsis enabled. Records are processed by the pipeline and then discarded before anything is buffered. No counter moves, and the target reports healthy. The only trace is one line at startup, and only whendebug.statusis enabled as well.Log sending is disabled for this target (elastic_output). Logs will be processed by the pipeline but will not be sent to the target. -
Only one of
usernameandpasswordis set. The batch then goes out with no authentication header. Against a cluster that allows anonymous access it is indexed under the anonymous role, wherever that role writes, with no warning at all. -
On
amazonopensearch, only one ofkeyandsecretis set. The pair is used only when both hold a value. Otherwise both are ignored and the default AWS credential chain is used instead, so the data may be written under the identity of the host rather than the one you configured. -
The records went to another index. An
indexfield set by a pipeline overrides the target's ownindexfor that record. Look for the documents under the name the pipeline produced before assuming they were never sent. -
A nested
tlsblock sits next to the flat TLS settings. The flatca_name,cert_name,key_nameandserver_nameare then ignored entirely, so keep every TLS option in one shape. An unrecognizedmin_tls_versionormax_tls_versionis ignored the same way: anything other thantls1.0throughtls1.3falls back to the defaults without an error. -
A custom
filter_pathdropsitems.*._index. Per-item errors then arrive with an empty index name, which makes them much harder to read. Keep the default, or includeitems.*._indexin your own value. -
Documents are indexed more than once. Any retry of a partly accepted chunk sends the whole chunk again. With
write_action: createand no document id the cluster generates a new id each time, so the duplicates are not detected and the delivered counter runs ahead of what the index holds.