Elastic Observability vs OpenTelemetry: Are We Finally on the "Right" Path?

Context

Our Elastic journey has been interesting and filled with trial and error. Around every corner we discover a different (and often better) way of doing the same thing, but it usually means redoing large parts of our setup. We’re getting a bit tired of rebuilding everything, so I’m hoping to get some advice that helps us skip a few corners and rediscoveries.

Below I have included our observability journey, and the questions are at the bottom.

Our Journey

ELK

We wanted to introduce observability for our applications and already had some prior experience with the ELK stack. We already used Elasticsearch, but added Kibana and started to push logs via Logstash.

We added a custom log line that we sent to a separate index, which we used for our dashboards and statistics.

2026-01-01 12:00:00 thread-01 MyClass.java: LOGSTASH [status:200][ip:xx.xx.xx.xx][duration:12]

Agents, Integration, Custom Logs (Filestream) & Pipeline

After running into some issues with Logstash, we discovered that Fleet Agents could install the Custom Logs (Filestream) integration and use our own ingest pipelines, effectively replacing Logstash entirely. At the time this felt like a better and more modern solution.

Kibana Observability

Later, we discovered Kibana Observability and realized that our existing solution didn’t integrate well with it. We then installed the Elastic APM integration on our agents and started using the Elastic Java Agent.

OpenTelemetry standard

After seeing how many other tools and frameworks we use support OpenTelemetry out of the box, we wanted to move toward the OTEL standard. However, we couldn’t get the standard OTEL SDKs to work directly with the Elastic APM integration or Kibana's Observability solution, so we switched from the Elastic Java Agent to the Elastic OTEL Java Agent.

This is where we started noticing feature gaps.

When using the Elastic OTEL Java Agent together with the Elastic APM integration:

  • Metric attributes appear to be dropped
  • Unmapped attributes are rewritten as labels.xxxx
  • Multiple Kibana's Observability Metrics visualizations not working
  • Other expected OTEL behaviors don’t seem to be fully supported

For example:

// pseudo
meter.histogramBuilder("my.histogram.name")  
        .setUnit("ms")  
        .ofLongs()  
        .build();
histrogram.record(12, Attributes.of("some.attribute", "some.value"));

The recorded metric ends up looking like this, with the attribute missing:

"my.histogram.name": { "counts": [4], "values": [6250] }

The Future (Maybe?)

After more research, it seems that we should not be using the Elastic APM integration at all, but instead:

  • Use the OpenTelemetry integration / EDOT OTEL Collector
  • Install the System OpenTelemetry Assets integration
  • Use default and standard OTEL SDKs and tooling
  • Let Elastic/Kibana consume OTEL semantic conventions over ECS

If that understanding is correct, this would allow us to stick to standard OTEL tooling while still using Elastic Observability effectively.

My lingering questions

  • Will using the OpenTelemetry integration / EDOT OTEL Collector allow us to use standard OTEL tools without labels.xxx, retain all metric attributes, and still have Kibana Observability fully working?
  • If we move to the OpenTelemetry integration / EDOT OTEL Collector, are we finally on the “recommended” path, or are we likely to discover yet another better approach and end up rebuilding again?
  • Is it currently possible to use default OpenTelemetry tools end-to-end together with the Elastic Observability solution?

We have similar concerns. Thanks for this post.

Hi Christoffer,

thank you for sharing your observability journey and the questions you have.

When using the EDOT Java agent or OTel vanilla you should ingest the data through an EDOT/OTel collector and/or Elastic Cloud Managed OTLP endpoint (reference architecture). The details depend on your environment. This ingestion path stores the telemetry data in Elasticsearch in the OTel-native format.

  • Is it currently possible to use default OpenTelemetry tools end-to-end together with the Elastic Observability solution?

You can use OTel vanilla SDKs/agents and an OTel collector to collect and ingest telemetry data. If you don't have the Elastic Cloud Managed OTLP endpoint on your ingest path you should tune the OTel contrib collector to have the right processing of data.

  • If we move to the OpenTelemetry integration / EDOT OTEL Collector, are we finally on the “recommended” path, or are we likely to discover yet another better approach and end up rebuilding again?

If you use an OTel-native ingestion path, that stores the telemetry in the OTel-native format in Elasticsearch, you should be on the right path. The APM server should not be part of this ingestion path because this would result in the telemetry data being stored in ECS format.

  • Will using the OpenTelemetry integration / EDOT OTEL Collector allow us to use standard OTEL tools without labels.xxx, retain all metric attributes, and still have Kibana Observability fully working?

If you use an OTel-native ingest path, you will have OTel's span, metrics and resource attributes. We have the Elastic's OTel demo environment available. It runs the OTel demo with a mix of EDOTs and OTel vanilla SDKs/agents. Maybe have a look and explore a bit. I recommend to use Discover to explore trace and metrics documents of the ingested data.

What kind of deployment of the Elastic Stack are you using and what version?

Thank you very much for the detailed answer.

We are running an on‑prem installation of Elasticsearch and Kibana. I believe most of our software is version 9.1.5. We are currently working on upgrading past 9.2+ as I believe the EDOT collector will be part of the 9.2+ Fleet Agents by default. Though haven't research if this means we don't need to install a separate collector or not. Ref.: Elastic Agent as an OpenTelemetry Collector

I have a few follow‑up questions to really hammer this home and make sure we’re aligning with the recommended architecture.

If I understand correctly, using an OTel‑native ingestion path (OTel SDKs/agents → OTel/EDOT Collector → Elasticsearch) will allow us to ingest all expected APM data.

What I’m still unsure about is whether Kibana’s Observability features will work out of the box in that scenario.

I believe I’ve seen references to installing specific content / assets packs (for example System OpenTelemetry Assets) to have Kibana correctly support OpenTelemetry semantic conventions, is that still required or recommended or needed?

You didn’t explicitly mention the EDOT Collector, which made me wonder:

  • Can we use the standard OpenTelemetry Collector instead of Elastic’s EDOT Collector?
  • If both are supported, what concrete benefits does the EDOT Collector provide over the vanilla collector?

If we fully move to an OTel Collector based ingestion path, am I correct in assuming that we can drop both:

  • the Elastic APM Agent, and
  • the elastic‑otel‑javaagent

…and instead rely on standard OpenTelemetry tooling such as:

  • native OTEL SDKs (io.opentelemetry:*)
  • framework integrations (for example Quarkus Micrometer OTEL, WildFly Micrometer OTEL bridge, etc.)

In other words: is the Elastic OTEL Java Agent optional if we are already instrumenting via SDKs/frameworks and exporting to a collector?

(Completely understandable if Java‑specific details are out of scope.)

Today we are attaching elastic-otel-javaagent-1.6.0.jar to the JVM and manually enriching traces using io.opentelemetry:opentelemetry-api. From your explanation, I understand that this results in data being converted and stored in ECS format, due to the Elastic APM integration.

If we introduce an OTel Collector and start ingesting OTEL‑native data in parallel during migration:

  • Will this cause issues for Kibana Observability, given that both ECS‑formatted and OTEL‑native telemetry would coexist temporarily?
  • Is there a recommended migration strategy to avoid breaking dashboards, correlations, or UI features while transitioning?

I will try to cover your questions in one reply.

  • You didn’t explicitly mention the EDOT Collector, which made me wonder

You are right. I did not mention the EDOT Collector explicitly only because I had the impression you are favouring the OTel contrib collector. The benefit of EDOT is that it contains an opinionated configuration for using OpenTelemetry with Elastic Observability. This applies to the EDOT SDKs and to the EDOT Collector. The EDOT SDKs are the upstream SDKs with an opinionated configuration in terms of default configuration settings and auto-instrumentation configuration (e.g. what instrumentation packages are enabled by default) in case of Java you can find more details here (config) and here (features). The EDOT compared to upstream OpenTelemetry page gives an overview on the differences between EDOT and upstream. The Elastic features available with EDOT table gives an overview on known Elastic APM features and their compatibility with EDOT. Known limitations of EDOT/OTel compared to Elastic APM data collection are documented too. For the EDOT SDKs we maintain a Feature overview table compared to Elastic APM agents. There are a few features like central configuration of EDOT SDKs that is currently only available with EDOTs and not with OTel vanilla SDKs/agents. We're working on contributing features to upstream e.g. the central configuration (issue#2546). If you are not using features only available in EDOT SDKs, you should be fine if you would like to choose OTel vanilla. Just make sure the data is collected and ingested expected by the integrations and pre-build dashboards. The EDOT collector contains several components like receivers, exporters, processors, connectors, extensions and providers (list of components). The benefit is you don't have to build your own custom collector with the necessary components included (see custom collector build) or make sure a contrib collector contains the required components. You can choose what better suites you. Using EDOTs and their benefits or using upstream vanilla/contrib.

  • What I’m still unsure about is whether Kibana’s Observability features will work out of the box in that scenario.

What features are you using in Kibana Observability? There are some limitations because some integrations and pre-build dashboards are designed for ECS-formatted data.

  • I believe I’ve seen references to installing specific content / assets packs (for example System OpenTelemetry Assets) to have Kibana correctly support OpenTelemetry semantic conventions, is that still required or recommended or needed?

We are building content packs for OpenTelemetry. The OpenTelemetry project is working on making things stable but changes are expected that can lead to changes in semantic conventions. Content packs are good to react to such changes in a flexible way. We can update the contained pre-build dashboards to be compatible with the updated semantic conventions.

  • In other words: is the Elastic OTEL Java Agent optional if we are already instrumenting via SDKs/frameworks and exporting to a collector?

IIUC this should be possible if you would like to do so. You point the OTLP exporter of the SDKs/frameworks to the OTLP receiver of your collector. What you should keep in mind is that framework integrations have to comply to OTel semantic conventions too. If they are not compliant with OTel semantic conventions you would have to build custom dashboards to visualise the data because integrations and pre-build dashboards are not finding the expected data they are looking for based on semantic conventions. You also need to check if the SDKs and the framework integrations collect the data you are looking for that the EDOT Java agent may collect out-of-the-box because of the opinionated configuration.

  • Today we are attaching elastic-otel-javaagent-1.6.0.jar to the JVM and manually enriching traces using io.opentelemetry:opentelemetry-api. From your explanation, I understand that this results in data being converted and stored in ECS format, due to the Elastic APM integration.

Right. If you run an EDOT collector you point the EDOT Java agent OTLP exporter to the collector and configure the Elasticsearch exporter to send the data to Elasticsearch:

exporters: elasticsearch/otel: endpoints: [ "${env:ELASTIC_ENDPOINT}" ] api_key: ${env:ELASTIC_API_KEY} mapping: mode: otel

I took this snippet from the sample configuration file for a standalone EDOT collector that is linked in the default configuration docs.

The data is then stored in OTel-native format. Such data is stored in OTel-native data streams.

  • If we introduce an OTel Collector and start ingesting OTEL‑native data in parallel during migration: Will this cause issues for Kibana Observability, given that both ECS‑formatted and OTEL‑native telemetry would coexist temporarily?

The data is stored in different data streams. A comparison between OpenTelemetry data streams to Elastic APM is available here. IIUC your question right, I would not expect issues.

  • Is there a recommended migration strategy to avoid breaking dashboards, correlations, or UI features while transitioning?

Because of the differences in ECS data and OTel-native data you have to update your assets like custom dashboards. This is necessary because the concepts are different. Taking JVM metrics as example. With Elastic APM Java agent we had the jvm.memory.heap.used metric and in OTel we have jvm.memory.used that needs to be filtered and aggregated on the metric attribute jvm.memory.type=heap. Replacing the queries of the dashboard panels with ES|QL queries enables the use of the COALESCE function. This allows to show ECS and OTel-native metrics in the same dashboard panels. In cases where OTel uses histograms, you would have to add a new dashboard panel to the dashboard to visualise it. In Java you would need to set OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=delta to enable delta temporality for the histograms to send them to Elasticsearch.

I hope I covered your questions. Let me know if I missed something. I avoided to write "it depends" on your environment. Please keep in mind that there can be details that rely do.

Again, thank you for your detailed response.

To summarize my current understanding, if we want to use standard OpenTelemetry tooling with Elasticsearch and Kibana Observability (assuming the frameworks and tooling follow OpenTelemetry semantic conventions):

  • For on‑prem deployments, it is recommended to use the EDOT Collector over a vanilla OTel collector, because it reduces mandatory and manual configuration.

  • Using standard OTel tooling with the EDOT Collector results in data being stored in OTel‑native format instead of ECS...

  • ... which means we should expect to:

    • Adapt Kibana Observability visualizations and queries where prebuilt assets are ECS‑specific.
    • Install and maintain OpenTelemetry content packs.
    • Configure OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=delta to support metric histograms in Elasticsearch.
  • ... and will result in:

    • No longer get labels.xxx attributes
    • No longer lose Metric attributes

I have no preference when it comes to EDOT Collector vs. the OTel Collector, my main issues have been:

  • We haven't been able to use third-party-software's OTel support out of the box with Kibana Observability.
  • Losing attributes when using the Java OTel SDK.
  • Not been able to fully utilize Metrics as we have lost attributes.
  • Not been able to use OTel SDK produced histograms with Kibana Visualizations.
  • For on‑prem deployments, it is recommended to use the EDOT Collector over a vanilla OTel collector, because it reduces mandatory and manual configuration.

Yes. It gives you comfort.

  • Using standard OTel tooling with the EDOT Collector results in data being stored in OTel‑native format instead of ECS...

Yes.

  • Adapt Kibana Observability visualizations and queries where prebuilt assets are ECS‑specific.

Yes. Consider to use ES|QL.

  • Install and maintain OpenTelemetry content packs.

Yes.

  • No longer get labels.xxx attributes

  • No longer lose Metric attributes

Yes.

  • I have no preference when it comes to EDOT Collector vs. the OTel Collector.

The EDOT Collector gives you comfort and less complexity because of the necessary components are already added. The provided sample configuration files help you to get started. You can switch to an OTel Collector when you have a specific demand.

I was curious about the Quarkus framework you mentioned and the OTel telemetry data it emits. I deployed the opentelemetry-quickstart (GitHub) app into my lab environment to explore it a bit. I'm using a Serverless project in my lab environment. I modified the application.properties file to look like this:

quarkus.application.name=quarkus-otel-quickstart

# OTel metrics off by default

quarkus.otel.metrics.enabled=true

# OTel logs off by default

quarkus.otel.logs.enabled=true

quarkus.otel.resource.attributes=deployment.environment=dev,service.name=quarkus-otel-quickstart

quarkus.otel.exporter.otlp.endpoint=my_motlp_endpoint:443

quarkus.otel.exporter.otlp.headers=Authorization=ApiKey my_api_key

#quarkus.otel.exporter.otlp.traces.headers=Authorization=Bearer my_secret

quarkus.log.console.format=%d{HH:mm:ss} %-5p traceId=%X{traceId}, parentId=%X{parentId}, spanId=%X{spanId}, sampled=%X{sampled} [%c{2.}] (%t) %s%e%n

# Don't run the Grafana LGTM dev service during tests

%test.quarkus.observability.enabled=false

I have added quarkus.otel.resource.attributes, quarkus.otel.exporter.otlp.endpoint, and quarkus.otel.exporter.otlp.headers to send the data to the mOTLP endpoint and set resource attributes that are recommended.

I send a couple of curl request to the REST API (not much just to get some data):

# Test the hello endpoint

curl http://localhost:8080/hello

# Test the chain endpoint  

curl http://localhost:8080/chain

# Test the metrics endpoint with a value parameter

curl http://localhost:8080/metrics/set?value=42

I looks good in Kibana. I haven't found anything that catched my attention immediately. Some screenshots attached. Traces, metrics and logs are there. You can see the metric attributes in Discover. The trace waterfall looks good.

Edit: Missed to upload the transaction screenshots

Thank you very much, an excellent reply! Next week we are upgrading from 9.1.x -> 9.3.x and will install the EDOT Collector and move away from the Elastic APM integrations.

I have also played around and installed the EDOT Collector in my k3s environment and done some Quarkus testing with the io.quarkus:quarkus-micrometer-opentelemetry extension and have yet to find any issues. Though, haven't touched Metrics much.

My pleasure :slight_smile:

Looking forward to hear about the results. If you are using Kubernetes, consider to utilize the OpenTelemetry Kubernetes Operator (OTel docs, GitHub). You may find this resource useful.

Thanks again for the clarification around EDOT and the OTel direction.

To make this more concrete for OpenShift-based environments, I’d like to validate whether the following architecture aligns with Elastic’s recommended and supported approach:

[OpenShift Cluster]

  • OTel Collector (Operator-managed, DaemonSet or Deployment)

  • Minimal processing (k8s enrichment, batching)

  • Export via OTLP↓

=> [Central Ingest / Gateway Tier]

  • OTel Collector (EDOT or upstream)

  • Aggregation, routing, buffering, multi-tenant handling↓

=> [Elastic (ECE)]

Questions:

  1. Is this hybrid model (in-cluster collectors + central gateway tier) considered a recommended / supported reference architecture by Elastic?
  2. Is EDOT intended to run in both layers, or primarily at the gateway tier?
  3. For OpenShift specifically, is Elastic Agent expected to replace the in-cluster OTel collectors over time, or should OTel Operator remain the preferred approach?
  4. Are there any known limitations or support boundaries for this model (e.g. Fleet-managed collectors, SCC constraints, buffering expectations)?

Trying to align with a production-grade design for regulated environments.

Thanks!

Hi willemdh,

the RedHat distro and operator integrates natively with the OpenShift security controls / context constraints and platform. It's a recommended choice to use it. The EDOT collector is supported on OpenShift but is not specialized to it.

For Central Ingest / Gateway the EDOT collector or an EDOT-like custom collector is recommended here. Just make sure you have all necessary components in the collector if you build your own.

  1. Is this hybrid model (in-cluster collectors + central gateway tier) considered a recommended / supported reference architecture by Elastic?

Yes. It's described in the Kubernetes reference architecture.

  1. Is EDOT intended to run in both layers, or primarily at the gateway tier?

You can run it on both layers.

  1. For OpenShift specifically, is Elastic Agent expected to replace the in-cluster OTel collectors over time, or should OTel Operator remain the preferred approach?

No. Only if you need a feature that is only provided by the Elastic Agent (e.g. Fleet Management).

  1. Are there any known limitations or support boundaries for this model (e.g. Fleet-managed collectors, SCC constraints, buffering expectations)?

If you run the RedHat distro in the OpenShift cluster and the EDOT Collector on the central ingest / gateway we would provide support for the ingest tier and thereafter.

I hope it helps you and provides the validation you are looking for.

A follow up instead of making a new thread.

We installed the EDOT Collector and tried to push OTel data from my java application with the elastic-otel-javaagent-1.11.0.jar. Don't remember why but changed the agent to opentelemetry-javaagent.jar instead and had more success. Does it make sense that we should use the default OTel java agent instead of the one elastic provides?

Now my new *-generic.otel-* index does not contain label attributes, and I do get the attributes for my metrics that was previously missing.

I'm still not able to get the Kibana > Observability > Service Inventory > Metrics > Visualizations to work correctly. Out of the box only 2/7 visualizations shows anything (image below). Why your screenshots and my previous testing with Quarkus worked out of the box, but this does not, I do not understand. The way I interpreted you previously was that I had to manually edit these visualizations, as they where meant for ESC. But I'm not able to save any changes I make to the Metrics page.

I have a few questions regarding the visualizations on the metrics page:

  • Is it possible to save changes made to the Kibana > Observability > Service Inventory > Metrics visualizations?
    • Does saving these changes apply for all Service Inventory applications or only the one metrics page I edit?
  • Are the metric page visualizations suppose to detect if we have OTel or ESC data?
    • Could the issue be that the default indexes the visualizations query is ESC?

I tried changing the default metric index pattern under Settings > Indices > Metrics Indices, thinking it would auto detect the OTel type and choose different visualization queries, but it did not work.

After manually editing the ES|QL for one of the visualizations, confirming that the query works looking at the ES|QL Query Results (image below), after applying the changes the visualization still shows nothing. No idea why.

Also the Use OpenTelemetry with Elastic APM | Elastic Docs page says:

To visualize data from OpenTelemetry receivers which is stored natively as OpenTelemetry semantic conventions, you must install content-only packs that provide dashboards compatible with OpenTelemetry data.

Does this only mean installing System OpenTelemetry Assets and does this content pack only give the 5 listed dashboards and have no other function? Will installing any content-packs affect the Kibana Observability pages? If so, which content-pack?

My goal is using OTel semantics and hopefully having all Kibana > Observability features work. And looking at your print screens and our previous Quarkus testing, it seems like it should work. But I must be doing something wrong.


Are you already running 9.3.x? You mentioned that you are planning an upgrade. Just to know what version are you using while making the experience you described.

Yes, Kibana is v9.3.3 and installed the EDOT Collector. We have a Wildfly running with the opentelemetry-javaagent.jar attached with:

JAVA_OPTS="$JAVA_OPTS -javaagent:/opentelemetry-javaagent.jar"
export OTEL_SERVICE_NAME=processor
export OTEL_EXPORTER_OTLP_ENDPOINT='http://127.0.0.1:4317'
export OTEL_EXPORTER_OTLP_PROTOCOL='grpc'
export OTEL_RESOURCE_ATTRIBUTES='service.version=1.0,deployment.environment.name=pilot'
export OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE='delta'
export OTEL_INSTRUMENTATION_RUNTIME_METRICS_ENABLED=true
export OTEL_INSTRUMENTATION_JDBC_ENABLED=false
export OTEL_LOGS_EXPORTER='otlp'

Our new OTel test data is configured to end up in data streams: logs-generic.otel-drift, traces-generic.otel-drift, metrics-generic.otel-drift. Looks like I was previously wrong, where both the default APM index pattern and the Settings > Indices > Metrics Indices does include our new OTel indexes in it's pattern.

The new OTel data streams, have conflicts on fields: attributes.server.port, server.port and status. But do not think that is what causing the problems.

So I made a new Space where I changed all Settings > Indice to match my new OTel only indexes, and now it looks like everything works. Now the Kibana Observability visualizations no longer queries fields/attributes in ECS.

My guess is therefore that when your indexes contains both OTel semantics and ECS it conflicts the ECS visualizations are chosen as default.

Interesting. So otel and ECS data is incompatible? Weird that you have to make a separate space to make it work imho.

No idea what the underlying cause is/was.

The default Settings > Indice > Metrics Indices pattern: metrics-apm*,apm-*,metrics-*.otel-* matched both my ECS and OTel indices. When inspecting Metric page visualizations they contained ECS specific fields such as: labels.jvm_memory_pool_name which obviously would not work with my indices containing pure OTel.

ES|QL for metric visualization: Limit & Commited & Used over @timestamp
from metrics-apm*,apm-*
| WHERE jvm.memory.committed IS NOT null AND labels.jvm_memory_type == "heap"
| KEEP @timestamp, labels.jvm_memory_pool_name, jvm.memory.used, jvm.memory.committed, jvm.memory.limit
| STATS used = SUM(jvm.memory.used), committed = SUM(jvm.memory.committed), limit = SUM(jvm.memory.limit) BY @timestamp
| STATS Limit = AVG(limit), Commited = AVG(committed), Used = AVG(used) BY @timestamp = BUCKET(@timestamp, 1000, ?_tstart, ?_tend)

I assumed that since we previously got the Metrics page to work with pure OTel when testing with Quarkus, that somehow Kibana detected the semantic type automatically.

I tried to change the Settings > Indice on my current Space, but that did not change the Metric page visualizations. I therefore tried to create a new space.

Can also mention that my application (service.name) had data in both ECS and OTel Indices. So I guessed that caused Kibana to not know which semantic type to chose. Tho, then I would think that changing Settings > Indice on the space should have worked. Maybe Kibana has stored a preferred semantic type for either the whole space or application?

There are some issues, specially if you want to do some custom parsing in your data, OTEL fields are flattened, with a dot in its name, ECS fields are not.

In OTEL you will have { "service.name" : "someName" }, but in ECS this is { "service" : { "name" : "someName" } }

If you have a custom ingest pipeline that want's to change this field for example, it will not work as the dot in the name breaks the processors, you would need to use the dot_expander processor first.

BTW @leandrojmp @nilsen

Ingest pipelines can now work on dotted / non-dotted fields

The default ingest pipeline access pattern does not recognize dotted field names in documents. Retrieving flattened and dotted field names from an ingest document requires a different field retrieval algorithm that does not have this limitation. We know that some pipelines have come to rely on these dotted field name limitations in their logic. In order to continue supporting the original behavior while still adding support for dotted field names, ingest pipelines now support configuring an access pattern to use for all processors in the pipeline.

The field_access_pattern property on an ingest pipeline defines how ingest document fields are read and written for all processors in the current pipeline. It accepts two values: classic (which is the default) and flexible.

Didn't knew about that, I build the ingest pipelines mostly using the Kibana UI, I do not see this option exposed in the UI in 9.4.1, I think it is missing?