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

  1. Break the cycle by removing or relaxing one @RelativeOrder(before/after) declaration among the ids listed in the message.
  2. Use only 'after' (or only 'before') edges in your own components to reduce conflict risk.
  3. 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

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


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/6e6fc004494fa09d. Report an issue: GitHub.