quarkusio/quarkus · error · IllegalArgumentException
Invalid Flyway callback. It shouldn't be abstract and must h
Error message
Invalid Flyway callback. It shouldn't be abstract and must have a default constructor
What it means
Quarkus discovers Flyway Callback beans by fully-qualified class name from the build-time index. A valid callback class must be concrete and provide a default constructor so it can be instantiated reflectively at deployment; otherwise this IllegalArgumentException is thrown.
Source
Thrown at extensions/flyway/deployment/src/main/java/io/quarkus/flyway/deployment/FlywayCallbacksLocator.java:90
* @exception InstantiationException if the {@link Callback} class represents an abstract class.
* @exception InvocationTargetException if the underlying constructor throws an exception.
* @exception IllegalAccessException if the {@link Callback} constructor is enforcing Java language access control
* and the underlying constructor is inaccessible
*/
private Collection<Callback> callbacksForDataSource(String dataSourceName)
throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException {
final Optional<List<String>> callbackConfig = flywayBuildConfig.datasources().get(dataSourceName).callbacks();
if (!callbackConfig.isPresent()) {
return Collections.emptyList();
}
final Collection<String> callbacks = callbackConfig.get();
final Collection<Callback> instances = new ArrayList<>(callbacks.size());
for (String callback : callbacks) {
final ClassInfo clazz = combinedIndexBuildItem.getIndex().getClassByName(DotName.createSimple(callback));
Objects.requireNonNull(clazz,
"Flyway callback not found, please verify the fully qualified name for the class: " + callback);
if (Modifier.isAbstract(clazz.flags()) || !clazz.hasNoArgsConstructor()) {
throw new IllegalArgumentException(
"Invalid Flyway callback. It shouldn't be abstract and must have a default constructor");
}
final Class<?> clazzType = Class.forName(callback, false, Thread.currentThread().getContextClassLoader());
final Callback instance = (Callback) clazzType.getConstructors()[0].newInstance();
instances.add(instance);
reflectiveClassProducer
.produce(ReflectiveClassBuildItem.builder(clazz.name().toString()).build());
}
return instances;
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Make the callback class concrete (non-abstract) and add a public no-argument constructor
- Point quarkus.flyway.callbacks at a concrete subclass that implements Callback
- Verify the fully qualified class name in configuration is correct
- If constructor args are needed, provide an additional no-arg constructor or use static/CDI-compatible instantiation
Example fix
// before
public abstract class MyCallback implements Callback { ... }
// after
public class MyCallback implements Callback {
public MyCallback() { }
...
} Defensive patterns
Strategy: validation
Validate before calling
Class<?> c = Class.forName(callbackName);
if (Modifier.isAbstract(c.getModifiers()))
throw new IllegalStateException(callbackName + " is abstract");
if (Arrays.stream(c.getConstructors()).noneMatch(k -> k.getParameterCount() == 0))
throw new IllegalStateException(callbackName + " has no default constructor"); Prevention
- Register only concrete classes with public no-arg constructors in quarkus.flyway.callbacks
- Double-check fully qualified class names in config
- Add a startup test that instantiates each configured callback
When it happens
Trigger: quarkus.flyway.<datasource>.callbacks lists a class that is abstract, or has no no-arg constructor; instantiation via getConstructors()[0].newInstance() then fails conceptually at validation time.
Common situations: Registering an abstract base Callback class instead of a concrete subclass; a callback with only parameterized constructors; after refactoring removed the default constructor; typos pointing at the wrong class.
Related errors
- Flyway migration location may not be null.
- Unable to instantiate SectionHelperFactory: <engineConfigCla
- Unable to instantiate ParserHook: <engineConfigClass>
- Unable to handle class: ${applicationClass}
- Failed to initialize
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/f7fd120ae7485686.
Report an issue: GitHub.