pinpoint-apm/pinpoint · error · ProfilerException
Target class is not modifiable
Error message
Target class is not modifiable
What it means
DynamicTransformService.retransform() first asserts via instrumentation.isModifiableClass() that the JVM allows retransforming the target class. Classes loaded without retention of bytecode needed for retransformation, or classes the JVM refuses (e.g. some bootstrap/generated classes), cannot be modified, so the agent throws ProfilerException.
Source
Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/transformer/DynamicTransformService.java:81
} finally {
if (!success) {
requestHandle.cancel();
}
}
}
@Override
public void addClassFileTransformer(ClassLoader classLoader, String targetClassName, ClassFileTransformer transformer) {
if (this.logger.isDebugEnabled()) {
logger.debug("Add dynamic transform. classLoader={}, class={}", classLoader, targetClassName);
}
this.dynamicTransformRequestListener.onTransformRequest(classLoader, targetClassName, transformer);
}
private void assertClass(Class<?> target) {
if (!instrumentation.isModifiableClass(target)) {
throw new ProfilerException("Target class " + target + " is not modifiable");
}
final JvmVersion version = JvmUtils.getVersion();
if (JAVA_8.compareTo(version) == 0) {
// If the version is java 8
// Java 8 bug - NoClassDefFound error in transforming lambdas(https://bugs.openjdk.java.net/browse/JDK-8145964)
final String className = target.getName();
if (className != null && className.contains("$$Lambda$")) {
throw new ProfilerException("Target class " + target + " is lambda class, Causes NoClassDefFound error in java 8.");
}
}
}
private void triggerRetransform(Class<?> target) {
try {
instrumentation.retransformClasses(target);
} catch (UnmodifiableClassException e) {
throw new ProfilerException(e);
}View on GitHub (pinned to 744c3d3075)
Solutions
- Verify with instrumentation.isModifiableClass(target) before calling retransform and skip/log instead
- Ensure the class bytecode version and classloader are supported by the JVM for retransformation
- Retransform only classes that were loaded normally and not stripped by another agent
- Upgrade the JVM if a known class-modifiability bug applies
Example fix
// before
transformService.retransform(clazz); // throws if not modifiable
// after
if (instrumentation.isModifiableClass(clazz)) {
transformService.retransform(clazz);
} else {
logger.warn("Skip retransform, not modifiable: {}", clazz.getName());
} Defensive patterns
Strategy: validation
Validate before calling
if (!instrumentation.isModifiableClass(target)) { skipRetransform(target); return; } Type guard
boolean canRetransform(Class<?> c) { return instrumentation != null && instrumentation.isModifiableClass(c); } Try / catch
try { transformService.retransform(clazz); } catch (ProfilerException e) { logger.warn("Cannot retransform {}: {}", clazz.getName(), e.getMessage()); } Prevention
- Always check isModifiableClass before dynamic retransform
- Avoid targeting classes produced by other instrumentation agents
- Test dynamic transforms on the target JVM version
When it happens
Trigger: Calling dynamicTransformService.retransform(Class) on a class for which Instrumentation.isModifiableClass() returns false, e.g. classes already transformed by another agent without retransformation support, or non-modifiable JVM classes.
Common situations: Trying to hot-apply Pinpoint transformers to classes loaded before the agent with unsupported bytecode versions; instrumenting generated/proxy classes; attaching agent to an already heavily-instrumented JVM.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- source and advice class node must not be null.
- ${after} method not found. ${Arrays.toString(afterParamList)
- ${after} must return java.lang.Object. ${targetInterceptorCl
- unknown scanner type classLoader:${classLoader} protectionDo
- unknown operand. operand=${operand}
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/3d6f4a4de3f9e190.
Report an issue: GitHub.