quarkusio/quarkus · error · IllegalArgumentException
The level of the root logger cannot be set to null
Error message
The level of the root logger cannot be set to null
What it means
LogStreamJsonRPCService.updateLogLevel() sets a java.util.logging level for a named logger. If levelValue is null/blank, it inherits the parent logger's level; but when the target logger has no parent (i.e. it is the root logger), there is nothing to inherit, so it throws IllegalArgumentException that the root logger level cannot be set to null.
Source
Thrown at extensions/devui/runtime/src/main/java/io/quarkus/devui/runtime/logstream/LogStreamJsonRPCService.java:98
"effectiveLevel", getEffectiveLogLevel(logger),
"configuredLevel", getConfiguredLogLevel(logger));
}
return null;
}
@NonBlocking
@JsonRpcDescription("Update a specific logger's log level in this Quarkus application")
@DevMCPEnableByDefault
public JsonObject updateLogLevel(@JsonRpcDescription("The name of the logger") String loggerName,
@JsonRpcDescription("The new level of the logger") String levelValue) {
LogContext logContext = LogContext.getLogContext();
Logger logger = logContext.getLogger(loggerName);
java.util.logging.Level level;
if (levelValue == null || levelValue.isBlank()) {
if (logger.getParent() != null) {
level = logger.getParent().getLevel();
} else {
throw new IllegalArgumentException("The level of the root logger cannot be set to null");
}
} else {
level = Level.parse(levelValue);
}
logger.setLevel(level);
LOG.info("Log level updated [" + loggerName + "] changed to [" + levelValue + "]");
return getLogger(loggerName);
}
private static String toLogLine(JsonObject json) {
return String.format(
"%s %s [%s] (%s) %s",
json.getString("timestamp"),
json.getString("level"),
json.getString("loggerName"),
json.getString("threadName"),
json.getString("formattedMessage"));View on GitHub (pinned to e1c734241f)
Solutions
- Send a valid level name (SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL, OFF)
- Only send null/blank level for non-root loggers to mean 'inherit parent'
- Guard in the Dev UI form to require a level when the target is the root logger
Example fix
// before
updateLogLevel("", ""); // root logger, blank level
// after
updateLogLevel("", "INFO"); // or pick a non-root logger for inheritance Defensive patterns
Strategy: validation
Validate before calling
const LEVELS = ['SEVERE','WARNING','INFO','CONFIG','FINE','FINER','FINEST','ALL','OFF']; if ((levelValue == null || levelValue === '') && isRootLogger(loggerName)) levelValue = 'INFO';
Type guard
const isKnownLevel = v => typeof v === 'string' && LEVELS.includes(v.toUpperCase());
Try / catch
try { rpc.call('logstream/updateLogLevel', { loggerName, levelValue }); }
catch (e) { if (String(e.message).includes('root logger')) { /* send an explicit level instead */ } else { throw e; } } Prevention
- Only send blank level for non-root loggers
- Constrain the Dev UI level selector to known JUL levels
- Default the root logger to INFO when clearing the input
When it happens
Trigger: Invoking the Dev UI log-stream JSON-RPC updateLogLevel with an empty or null level for the root logger (loggerName empty or "" resolving to a parentless logger).
Common situations: Front-end sending an empty level string when the user clears the level input for the ROOT logger; also triggered by Level.parse failing separately for garbage values.
Related errors
- Expected a base64 encoded byte array, got: ${text}
- messageStarts cannot be empty
- Unimplemented mode of use of 'io.quarkus.runtime.logging.Log
- Offending class is '${className}'
- Filter '${filterName}' was defined multiple times.
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/910c8182d251caa4.
Report an issue: GitHub.