apache/cassandra · error · RuntimeException
Unsupported injectable field type: in class . Only INodePro
Error message
Unsupported injectable field type: in class . Only INodeProbeFactory and Output are supported.
What it means
NodeTool uses a small dependency-injection mechanism to populate @Inject annotated fields on command classes. Only two injectable types are supported: INodeProbeFactory and Output. Any command declaring an @Inject field of another type triggers this RuntimeException during bean creation.
Source
Thrown at src/java/org/apache/cassandra/tools/NodeTool.java:345
{
Field[] fields = beanClass.getDeclaredFields();
for (Field field : fields)
{
if (!field.isAnnotationPresent(Inject.class))
continue;
if (field.getType().equals(INodeProbeFactory.class))
{
field.setAccessible(true);
field.set(bean, nodeProbeFactory);
}
else if (field.getType().equals(Output.class))
{
field.setAccessible(true);
field.set(bean, output);
}
else
{
throw new RuntimeException("Unsupported injectable field type: " + field.getType() +
" in class " + beanClass.getName() + ". " +
"Only INodeProbeFactory and Output are supported.");
}
}
}
while ((beanClass = beanClass.getSuperclass()) != null);
return bean;
}
catch (Exception e)
{
throw new CommandLine.InitializationException("Failed to create instance of " + cls, e);
}
}
}
}
View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Change the field type to INodeProbeFactory (and call create() on it to get a NodeProbe) or Output
- Remove the @Inject annotation and obtain the dependency inside the command body instead
- If you need a NodeProbe, inject INodeProbeFactory and have the factory construct it
Example fix
// before
@Inject
private NodeProbe probe;
// after
@Inject
private INodeProbeFactory nodeProbeFactory;
...
try (NodeProbe probe = nodeProbeFactory.create()) { /* use probe */ } Defensive patterns
Strategy: validation
Validate before calling
for (Field f : commandClass.getDeclaredFields())
if (f.isAnnotationPresent(Inject.class)
&& !INodeProbeFactory.class.isAssignableFrom(f.getType())
&& !Output.class.isAssignableFrom(f.getType()))
throw new IllegalStateException("Unsupported @Inject type: " + f.getType()); Type guard
static boolean isInjectable(Class<?> t) {
return INodeProbeFactory.class.isAssignableFrom(t) || Output.class.isAssignableFrom(t);
} Try / catch
try { toolFactory.create(Cmd.class); }
catch (RuntimeException e) { LOG.error("command wiring failed", e); } Prevention
- Only inject INodeProbeFactory or Output in nodetool commands
- Obtain other dependencies inside execute(), not via injection
- Re-check inherited fields when moving @Inject fields to superclasses
When it happens
Trigger: Declaring an @Inject (NodeTool's injection annotation) field whose declared type is neither INodeProbeFactory nor Output in a NodeTool command (or a superclass of one), then invoking that command — create() iterates fields up the class hierarchy and throws on the first unsupported type.
Common situations: Developers writing custom nodetool commands try to inject a probe implementation class, a configuration object, or a service instead of using INodeProbeFactory/Output; refactoring moves an injected field into a parent class so it now gets scanned.
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
- Failed to create instance of
- Invalid comparator class %s: must define a public static ins
- Properties specified %s are not understood by %s
- %s.validateOptions() threw an error: %s %s
- Cannot access method validateOptions in
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/35903c67965617ca.
Report an issue: GitHub.