quarkusio/quarkus · error · IllegalArgumentException
'$' must always be followed by '{'
Error message
'$' must always be followed by '{' What it means
In ClientHeaderParam values, '$' only introduces configuration expressions in the ${property} form. A '$' followed by any character other than '{' (e.g. $token) is rejected at build time with IllegalArgumentException, since bare $name syntax is not supported.
Source
Thrown at extensions/resteasy-reactive/rest-client/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/MicroProfileRestClientEnricher.java:1182
// this is a pretty naive implementation, but it suffices for what we are trying to do
List<Node> parse() {
int i = 0;
int configStart = -1;
int accessibleStart = -1;
int verbatimStart = -1;
List<Node> nodes = new ArrayList<>();
while (i < input.length()) {
char c = input.charAt(i);
if (c == '$') {
if ((configStart != -1) || (accessibleStart != -1)) {
throw new IllegalArgumentException(createEffectiveErrorMessage("Cannot mix expressions"));
}
if (i == input.length() - 1) {
throw new IllegalArgumentException(createEffectiveErrorMessage("Illegal end of expression"));
}
if (input.charAt(i + 1) != '{') {
throw new IllegalArgumentException(createEffectiveErrorMessage("'$' must always be followed by '{'"));
}
if (verbatimStart != -1) {
nodes.add(new Verbatim(input.substring(verbatimStart, i)));
}
i += 2;
configStart = i;
verbatimStart = -1;
} else if (c == '{') {
if ((configStart != -1) || (accessibleStart != -1)) {
throw new IllegalArgumentException(createEffectiveErrorMessage("Cannot mix expressions"));
}
if (i == input.length() - 1) {
throw new IllegalArgumentException(createEffectiveErrorMessage("Illegal end of expression"));
}
if (verbatimStart != -1) {
nodes.add(new Verbatim(input.substring(verbatimStart, i)));
}
i++;View on GitHub (pinned to e1c734241f)
Solutions
- Use the full ${property} syntax: "$value" becomes "${value}"
- Remove the '$' if it was meant as literal text
- Move dollar-containing literal text so '$' is never directly followed by a non-'{' character, or use a method reference to produce the value
Example fix
// before
@ClientHeaderParam(name="X-Build", value="$buildId")
// after
@ClientHeaderParam(name="X-Build", value="${buildId}") Defensive patterns
Strategy: validation
Validate before calling
String v = "$buildId";
for (int i = 0; i < v.length(); i++) {
if (v.charAt(i) == '$' && (i == v.length() - 1 || v.charAt(i + 1) != '{')) {
throw new IllegalArgumentException("'$' must be followed by '{': " + v);
}
} Prevention
- Always write config lookups as ${property}, never $property
- Escape or remove literal '$' characters in header text
- Search codebase for "\$[^{]" in annotation values during code review
When it happens
Trigger: Values like "$version" or "prefix-$value" inside @ClientHeaderParam — a '$' not immediately followed by '{'.
Common situations: Habit from Spring/property-placeholder syntax ($key instead of ${key}), or template strings containing currency amounts like "$100".
Related errors
- Cannot mix expressions
- Illegal end of expression
- 'quarkus-narayana-lra' can only work if 'quarkus-rest-client
- Token exchange is required but OIDC client is configured to
- Not possible to define the scope %s for the REST client %s
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/2ba5c2244debdef1.
Report an issue: GitHub.