Failure store in Elastic 9.2: rejected logs no longer vanish
Elastic 9.2, released on 23 October 2025, turns on the failure store for new log data streams. What changes for clients and how to find errors.
Elastic 9.2 was released on 23 October 2025. The announcement is dominated by AI agents and vector search, but anyone who looks after logs should notice a change that Elastic lists among the main novelties of Elasticsearch 9.2: the failure store is now enabled by default for new log data streams whose names match the logs-*-* pattern. The mechanism was introduced in version 9.1. The new default in 9.2 means it works in clusters where nobody switched it on deliberately, and it also changes how the write response behaves. It is worth knowing exactly what happens.
The problem it solves
Until now a document that Elasticsearch could not store came back to the client as an error. The cause was an exception in the ingest pipeline or a conflict with the mapping, for example a field defined as a number to which an application sent text. Many programs that ship logs have no sensible handling for such an error and simply drop the document. For logs this means that an event that could have been an important signal disappears without a trace, often just when the log format changes after an application update.
The failure store is an additional set of indices inside a data stream, meant for such documents. Elasticsearch accepts the faulty document, stores it together with the event time and a description of the error, and tells the client that it was redirected. The mechanism does not cover errors caused by overload (backpressure), permissions or document version conflicts: those always go back to the client, because they need its reaction.
What changes for clients
The release note for 9.2 says it plainly: when the failure store is enabled, the response code for writing an invalid document changes from 400 Bad Request to 201 Created, and the response gets an additional attribute "failure_store": "used". In a bulk write (_bulk) the item with a redirected document also has status 201 and the same attribute.
This is a change you must reflect in monitoring. If a program, script or alert reacts to 400 codes on write, after the upgrade it will stop seeing the problem even though documents are still being rejected. Errors now have to be searched for in the failure store, or you have to check the failure_store attribute in the response. The other values of that attribute are not_enabled (the mechanism could have accepted the document but is off, so the error comes back as before) and failed (writing to the failure store did not succeed, for example because a shard was unavailable).
How to enable it where it does not work by itself
The default applies to new logs-*-* data streams. For other data streams, including logs in version 9.1 and earlier, you have to enable the mechanism yourself. There are three ways.
In the index template, for new data streams:
PUT _index_template/my-template
{
"index_patterns": ["application-*"],
"data_stream": {},
"template": {
"data_stream_options": { "failure_store": { "enabled": true } }
}
}
For a data stream that already exists (the data_stream_options section of a template applies only when the stream is created):
PUT _data_stream/application-production/_options
{ "failure_store": { "enabled": true } }
For many data streams at once, with the cluster setting data_streams.failure_store.enabled, which takes a list of name patterns. Options set on the data stream itself take precedence over this setting. The 9.2 notes also say the mechanism is enabled for newly created OpenTelemetry data streams.
How to look for errors
Faulty documents sit in separate indices, so ordinary queries do not show them. You add the ::failures selector to the data stream name:
FROM logs-*::failures
| WHERE @timestamp > NOW() - 1 day
| STATS errors = COUNT(*) BY document.index, error.type
| SORT errors DESC
This summary immediately shows which data streams and which kinds of error are the most frequent. A document in the failure store contains the time of the error, the identifier and name of the data stream, the content of the original document (in the document.source field), the type and message of the error and, for pipeline errors, the name of the pipeline and processor. After you fix the mapping or the pipeline, the faulty documents can be reindexed instead of lost.
In Kibana, from version 9.1, the Data Set Quality page shows failure store metrics, and the interface tells you when the mechanism is not enabled for a data stream.
Retention and sensitive data
By default, data in the failure store is kept for 30 days, through an internal data stream lifecycle. You can change the period with the cluster setting data_streams.lifecycle.retention.failures_default or in the options of a single data stream, and the maximum retention set in the cluster also applies. When you enable the mechanism, pay attention to two points from the documentation.
First, a document redirected after a pipeline error lands in the failure store in its original, unprocessed form. If the pipeline hides sensitive data (masks numbers, removes fields), the failure store may hold the unmasked version. That is why access requires a separate read_failure_store privilege on the data stream. Grant it narrowly and include it in your permissions review.
Second, faulty documents have a different structure from normal data. If you use document-level or field-level security (DLS and FLS), rules written for normal documents may not work the same way for failure store documents.
What else in 9.2 for people who work with ES|QL
The LOOKUP JOIN command, which we described in our article on log enrichment in ES|QL, supports matching on several fields and remote indices (cross-cluster search) in 9.2. Matching on expressions, for example with greater-than or less-than operators, is a technical preview in this version. There are also commands for time series analysis, including TS.
What to do after the upgrade
- Check whether any alert or script relies on the 400 code on write, and replace it with a check of the failure store.
- Decide who may read
::failures, and whether pipelines that mask data need extra care. - Enable the mechanism for the existing log data streams that matter most to you, then for the rest.
- Build one dashboard or alert with the number of errors per day. A sudden rise usually means an application changed its log format.
If you are upgrading from 8.x, first read our article on the order of upgrading from 8.x to 9.x. We set up the failure store and the privileges for it as part of log management.