# Stable analysis plugin with native library fails entitlements in Elasticsearch 8.19.12

**URL:** <https://discuss.elastic.co/t/stable-analysis-plugin-with-native-library-fails-entitlements-in-elasticsearch-8-19-12/386411>\
**Category:** Elasticsearch\
**Tags:** docker, runtime-fields\
**Created:** [May 19, 2026, 3:34pm UTC](https://discuss.elastic.co/t/stable-analysis-plugin-with-native-library-fails-entitlements-in-elasticsearch-8-19-12/386411 "2026-05-19T15:34:36Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![dbenito](https://avatars.discourse-cdn.com/v4/letter/d/958977/32.png) [@dbenito](https://discuss.elastic.co/u/dbenito)\
**Post date:** [May 19, 2026, 3:34pm UTC](https://discuss.elastic.co/t/stable-analysis-plugin-with-native-library-fails-entitlements-in-elasticsearch-8-19-12/386411/1 "2026-05-19T15:34:36Z")

</div>

# Stable analysis plugin with native library fails entitlements in Elasticsearch 8.19.12

We are building a stable-analysis plugin that registers a custom `TokenFilter` via the stable plugin API. The plugin needs to load a bundled native library.

The plugin works in Gradle-managed `yamlRestTest`, but in Docker Elasticsearch `8.19.12` it fails on the first `_analyze` call with a native-loading entitlement error.

## Environment

- Elasticsearch Docker image: `docker.elastic.co/elasticsearch/elasticsearch:8.19.12`
- Plugin type: stable-analysis plugin
- Component type: custom `TokenFilter`
- Native library: bundled inside the plugin resources and loaded at runtime
- Plugin ZIP installs successfully
- Plugin appears in `_cat/plugins` / `_nodes/plugins`
- Node starts successfully before the first `_analyze` request

## Runtime failure

On the first `_analyze` request, the node exits with:

```plaintext
Not entitled: component [acme-analysis],
module [synthetic.acme.analysis],
class [class com.acme.EmbeddedLibraryTools],
entitlement [load_native_libraries]

```

The relevant class is the one that ultimately calls `System.load(...)` for the extracted native library.

## Entitlement policy tried: `ALL-UNNAMED`

We added the following file:

```plaintext
src/main/plugin-metadata/entitlement-policy.yaml

```

with this content:

```yaml
ALL-UNNAMED:
  - load_native_libraries

```

The policy is packaged at the root of the plugin ZIP and is installed correctly.

We verified all three copies:

- source file
- ZIP contents
- installed plugin directory under `/usr/share/elasticsearch/plugins/acme-analysis/`

All contain exactly:

```yaml
ALL-UNNAMED:
  - load_native_libraries

```

Docker logs also show that Elasticsearch sees the entitlement request:

```plaintext
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: plugin requires additional entitlements @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
* load_native_libraries

```

The JVM arguments also include:

```plaintext
--enable-native-access=ALL-UNNAMED

```

Despite that, the first `_analyze` request still fails with:

```plaintext
Not entitled: component [acme-analysis], module [synthetic.acme.analysis], class [class com.acme.EmbeddedLibraryTools], entitlement [load_native_libraries]

```

So `ALL-UNNAMED` is accepted and appears to enable native access for `ALL-UNNAMED`, but the runtime entitlement check attributes the call to `synthetic.acme.analysis` instead.

## Entitlement policy tried: `synthetic.acme.analysis`

We then tried targeting the runtime-reported module directly:

```yaml
synthetic.acme.analysis:
  - load_native_libraries

```

That fails during Elasticsearch boot with:

```plaintext
Invalid module name in policy: layer [acme-analysis] does not have module [synthetic.acme.analysis]; available modules [ALL-UNNAMED]; policy path [/usr/share/elasticsearch/plugins/acme-analysis/entitlement-policy.yaml]

```

So the policy validator says the plugin layer only exposes:

```plaintext
ALL-UNNAMED

```

but the runtime entitlement failure reports:

```plaintext
synthetic.acme.analysis

```

## Helper module experiment

We also tried moving the actual `System.load(...)` call into a separate helper JAR included in the stable plugin ZIP.

The helper JAR is an explicit Java module:

```plaintext
acme.nativebridge

```

It contains:

```plaintext
com.acme.nativebridge.NativeLibraryLoader

```

and the actual native-loading call is now inside that helper class:

```java
System.load(...)

```

The helper JAR is packaged at the root of the plugin ZIP:

```plaintext
nativebridge-0.0.1.jar

```

`jar --describe-module` reports it as an explicit module:

```plaintext
acme.nativebridge

```

We then used this entitlement policy:

```yaml
acme.nativebridge:
  - load_native_libraries

```

But Elasticsearch `8.19.12` rejects it at boot:

```plaintext
Invalid module name in policy: layer [acme-analysis] does not have module [acme.nativebridge]; available modules [ALL-UNNAMED]; policy path [/usr/share/elasticsearch/plugins/acme-analysis/entitlement-policy.yaml]

```

So even an explicit helper module packaged inside the stable-analysis plugin ZIP does not appear to be visible to the entitlement policy validator. The validator still reports only:

```plaintext
ALL-UNNAMED

```

## Summary of what we have confirmed

1. The plugin ZIP is mounted and installed correctly.
2. `entitlement-policy.yaml` is packaged and installed correctly.
3. `ALL-UNNAMED` is accepted by Elasticsearch.
4. Elasticsearch logs show `load_native_libraries` as a required entitlement.
5. Elasticsearch JVM args include `--enable-native-access=ALL-UNNAMED`.
6. The node starts and the plugin is visible before `_analyze`.
7. The first `_analyze` request still fails because the native load is attributed to `synthetic.acme.analysis`.
8. Targeting `synthetic.acme.analysis` directly is rejected by the policy validator.
9. A separately packaged explicit helper module is also rejected by the policy validator; the validator still reports only `ALL-UNNAMED`.
10. The same plugin works in Gradle-managed `yamlRestTest`, but not in real Docker Elasticsearch `8.19.12`.

## Question

Can stable-analysis plugins in Elasticsearch `8.19.x` load native libraries under the entitlement system?

If yes, what should the `entitlement-policy.yaml` scope be for a stable-analysis plugin whose runtime entitlement failure reports:

```plaintext
module [synthetic.acme.analysis]

```

when the policy validator only accepts:

```plaintext
ALL-UNNAMED

```

If no, is native library loading under the new entitlement system only supported for classic plugins in `8.19.x`?

More generally: how should a stable-analysis plugin that needs `load_native_libraries` be packaged and scoped in `entitlement-policy.yaml`?
