elastic/elasticsearch · critical · IllegalStateException
An internal error occurred attempting to define the factory
Error message
An internal error occurred attempting to define the factory class [{}]. What it means
PainlessScriptEngine throws this IllegalStateException when the dynamically generated script factory class cannot be instantiated via reflection. After the compiler writes the factory bytecode and defines it through the loader, it calls factory.getConstructor().newInstance(); any failure (NoSuchMethodException, SecurityException, IllegalAccessException, InstantiationException, InvocationTargetException) is wrapped in this generic error. This is an internal compiler/infrastructure failure, not a user script error.
Source
Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngine.java:357
GeneratorAdapter deterAdapter = new GeneratorAdapter(
Opcodes.ASM5,
isResultDeterministic,
writer.visitMethod(Opcodes.ACC_PUBLIC, methodName, isResultDeterministic.getDescriptor(), null, null)
);
deterAdapter.visitCode();
deterAdapter.push(scriptScope.isDeterministic());
deterAdapter.returnValue();
deterAdapter.endMethod();
writer.visitEnd();
Class<?> factory = loader.defineFactory(className.replace('/', '.'), writer.toByteArray());
try {
return context.factoryClazz.cast(factory.getConstructor().newInstance());
} catch (Exception exception) {
// Catch everything to let the user know this is something caused internally.
throw new IllegalStateException(
"An internal error occurred attempting to define the factory class [" + className + "].",
exception
);
}
}
private static void writeNeedsMethods(Class<?> clazz, ClassWriter writer, Set<String> extractedVariables) {
for (Method method : clazz.getMethods()) {
if (method.getName().startsWith("needs")
&& method.getReturnType().equals(boolean.class)
&& method.getParameterTypes().length == 0) {
String name = method.getName();
name = name.substring(5);
name = Character.toLowerCase(name.charAt(0)) + name.substring(1);
org.objectweb.asm.commons.Method needs = new org.objectweb.asm.commons.Method(
method.getName(),
MethodType.methodType(boolean.class).toMethodDescriptorString()View on GitHub (pinned to db6a809a66)
Solutions
- Check the caused-by exception (the 'exception' argument) for the root cause — it names the actual reflective failure.
- If caused by SecurityManager/permissions, ensure the Elasticsearch security policy permits reflective access to generated script classes.
- If no obvious cause, report a Painless bug with the script source, ES version, and JDK version; this is not expected under normal operation.
Defensive patterns
Strategy: try-catch
Try / catch
// This is an internal error; inspect the caused-by exception:
// try { scriptEngine.compile(...); } catch (IllegalStateException e) { log.error('factory init failed', e.getCause()); } Prevention
- Keep Elasticsearch and the JDK on supported, compatible versions.
- Review the caused-by exception for the root reflective failure.
- Report reproducible cases as Painless bugs with full version info.
When it happens
Trigger: The factory class was generated but its no-arg constructor is missing, inaccessible, or threw during execution. This typically indicates a Painless compiler bug, a classloader/SecurityManager restriction, an ASM version mismatch, or bytecode generation corruption.
Common situations: Running a Painless build with incompatible ASM or JDK versions. Custom security managers blocking reflective instantiation. Bugs in the Painless compiler that emit malformed factory bytecode. Rare edge cases in script compilation.
Related errors
- Painless can only implement interfaces that have a single me
- no execute method found
- convertFromDef must take a single Object as an argument, not
- [{}#ARGUMENTS] has length [2] but [{}#execute] takes [1] arg
- Painless needs a constant [String[] PARAMETERS] on all inter
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/a8cc2e1eee7035dc.
Report an issue: GitHub.