quarkusio/quarkus · error · IllegalStateException
Cycle detected in @RelativeOrder declarations involving s:
Error message
Cycle detected in @RelativeOrder declarations involving s:
What it means
Components are ordered with a topological sort of their @RelativeOrder declarations. When the relative-order constraints form a cycle (A before B before A), no total order exists and the build fails with the set of ids stuck in the cycle.
Source
Thrown at extensions/signals/deployment/src/main/java/io/quarkus/signals/deployment/TopologicalSort.java:90
}
List<String> sorted = new ArrayList<>();
while (!queue.isEmpty()) {
String node = queue.poll();
sorted.add(node);
for (String neighbor : graph.get(node)) {
int newDegree = inDegree.get(neighbor) - 1;
inDegree.put(neighbor, newDegree);
if (newDegree == 0) {
queue.add(neighbor);
}
}
}
if (sorted.size() != allIds.size()) {
Set<String> remaining = new HashSet<>(allIds);
remaining.removeAll(sorted);
throw new IllegalStateException(
"Cycle detected in @RelativeOrder declarations involving " + componentTypeName + "s: " + remaining);
}
return sorted;
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Break the cycle by removing or relaxing one @RelativeOrder(before/after) declaration among the ids listed in the message.
- Use only 'after' (or only 'before') edges in your own components to reduce conflict risk.
- If the cycle comes from libraries, override ordering by giving your bean explicit non-cyclic constraints or update/remove an extension.
Example fix
// before
@Identifier("a") @RelativeOrder(after = "b") class A ...
@Identifier("b") @RelativeOrder(after = "a") class B ...
// after
@Identifier("a") class A ...
@Identifier("b") @RelativeOrder(after = "a") class B ... Defensive patterns
Strategy: validation
Validate before calling
// Detect cycles in before/after edges before build: Map<String,Set<String>> edges = ...; // 'after' constraints // run Kahn's algorithm; if sorted.size() < nodes.size() -> cycle
Prevention
- Use one-directional ordering constraints (only 'after') for your components.
- Keep @RelativeOrder minimal; rely on defaults when order does not matter.
- Document ordering intent per component to avoid mutual before/after declarations.
When it happens
Trigger: Two or more SPI component beans whose @RelativeOrder(before/after) constraints reference each other circularly, or a self-reference.
Common situations: Two library enrichers each declaring they come after the other, or a user component wedged between two mutually ordered components.
Related errors
- Failed to open path tree with root %s
- Dev services for ${request.getName()} requires a startable s
- Name cannot start with '/':${name}
- The class (${name}) cannot be created during deployment.
- Use GeneratedServiceProviderBuildItem to register service pr
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/6e6fc004494fa09d.
Report an issue: GitHub.