elastic/elasticsearch · error · IllegalArgumentException

script context [{}] not found

Error message

script context [{}] not found

What it means

PainlessContextAction handles GET /_scripts/painless/_context. When a specific context name is requested (request.scriptContextName != null), it iterates the engine's registered contexts and if none matches, throws IllegalArgumentException 'script context [name] not found'. The name is interpolated from the request.

Source

Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/action/PainlessContextAction.java:174

                    .stream()
                    .map(v -> v.name)
                    .collect(Collectors.toList());
                painlessContextInfo = null;
            } else {
                ScriptContext<?> scriptContext = null;
                PainlessLookup painlessLookup = null;

                for (Map.Entry<ScriptContext<?>, PainlessLookup> contextLookupEntry : painlessScriptEngine.getContextsToLookups()
                    .entrySet()) {
                    if (contextLookupEntry.getKey().name.equals(request.getScriptContextName())) {
                        scriptContext = contextLookupEntry.getKey();
                        painlessLookup = contextLookupEntry.getValue();
                        break;
                    }
                }

                if (scriptContext == null || painlessLookup == null) {
                    throw new IllegalArgumentException("script context [" + request.getScriptContextName() + "] not found");
                }

                scriptContextNames = Collections.emptyList();
                painlessContextInfo = new PainlessContextInfo(scriptContext, painlessLookup);
            }

            listener.onResponse(new Response(scriptContextNames, painlessContextInfo));
        }
    }

    public static class RestAction extends BaseRestHandler {

        @Override
        public List<Route> routes() {
            return List.of(new Route(GET, "/_scripts/painless/_context"));
        }

        @Override

View on GitHub (pinned to db6a809a66)

Solutions

  1. Call GET /_scripts/painless/_context with no context name to list all available context names, then use one from that list.
  2. Install/enable the plugin that provides the desired context.
  3. Verify ES version matches the documented context name.

Example fix

// before
GET /_scripts/painless/_context
{ "script_context": "filteer" } // typo -> 1350
// after
GET /_scripts/painless/_context
{ "script_context": "filter" }
Defensive patterns

Strategy: validation

Validate before calling

// Before calling _context with a name, fetch the list of valid names:
// GET /_scripts/painless/_context  (no name) -> Response.scriptContextNames contains valid values.
Set<String> valid = new HashSet<>(response.scriptContextNames);
if (!valid.contains(requestedName)) throw new IllegalArgumentException("unknown context");

Try / catch

try {
    client.execute(PainlessContextAction.INSTANCE, request);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("script context [") && e.getMessage().endsWith("not found")) {
        // re-fetch available contexts and retry with a corrected name
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling the painless _context API with a context name that is not registered with the PainlessScriptEngine — e.g. a typo, a context provided by a plugin that is not installed, or a context name from a newer/older ES version.

Common situations: Querying documentation for a context name; plugin not loaded due to deployment issue; version skew between client and server context names; casing/typo in the request.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/34940fddc4c88369. Report an issue: GitHub.