{"record":{"id":"87e69654a34fa2ac","repo":"SonarSource/sonarqube","slug":"log-level-s-in-property-s-is-not-a-supported-val","errorCode":null,"errorMessage":"log level %s in property %s is not a supported value (allowed levels are %s)","messagePattern":"log level (.+?) in property (.+?) is not a supported value \\(allowed levels are (.+?)\\)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"server/sonar-process/src/main/java/org/sonar/process/logging/AbstractLogHelper.java","lineNumber":81,"sourceCode":"    for (String propertyKey : propertyKeys) {\n      Level level = getPropertyValueAsLevel(props, propertyKey);\n      if (level != null) {\n        newLevel = level;\n      }\n    }\n    return newLevel;\n  }\n\n  @CheckForNull\n  static Level getPropertyValueAsLevel(Props props, String propertyKey) {\n    String value = props.value(propertyKey);\n    if (value == null) {\n      return null;\n    }\n\n    Level level = Level.toLevel(value, Level.INFO);\n    if (!isAllowed(level)) {\n      throw new IllegalArgumentException(format(\"log level %s in property %s is not a supported value (allowed levels are %s)\",\n        level, propertyKey, Arrays.toString(ALLOWED_ROOT_LOG_LEVELS)));\n    }\n    return level;\n  }\n\n  static boolean isAllowed(Level level) {\n    for (Level allowedRootLogLevel : ALLOWED_ROOT_LOG_LEVELS) {\n      if (level.equals(allowedRootLogLevel)) {\n        return true;\n      }\n    }\n    return false;\n  }\n}\n","sourceCodeStart":63,"sourceCodeEnd":96,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-process/src/main/java/org/sonar/process/logging/AbstractLogHelper.java#L63-L96","documentation":"AbstractLogHelper.getPropertyValueAsLevel reads a logging level property and converts it with Log4j Level.toLevel (defaulting to INFO when unparseable). If the resulting level is not among ALLOWED_ROOT_LOG_LEVELS, it throws IllegalArgumentException listing the allowed levels.","triggerScenarios":"Setting sonar.log.level (or a per-process log level property like sonar.web.logLevel) to a value outside the allowed set (TRACE, DEBUG, INFO, WARN, ERROR), e.g. \"verbose\", \"warning\", or \"FATAL\".","commonSituations":"Users copying log level names from other frameworks (logback/Jul \"warning\", \"fatal\") into sonar.properties; mixed-case or padded values; changing log level at runtime via web API with a bad value.","solutions":["Set the property to one of the allowed levels: TRACE, DEBUG, INFO, WARN, ERROR.","Replace unsupported synonyms (e.g. WARNING -> WARN, FATAL -> ERROR, VERBOSE -> DEBUG).","Trim whitespace and check casing if the value looks correct but still rejected."],"exampleFix":"// before\nsonar.log.level=warning\n// after\nsonar.log.level=WARN","handlingStrategy":"validation","validationCode":"Set<String> ALLOWED = Set.of(\"TRACE\", \"DEBUG\", \"INFO\", \"WARN\", \"ERROR\");\nString lvl = props.value(\"sonar.log.level\");\nif (lvl != null && !ALLOWED.contains(lvl.trim().toUpperCase(Locale.ROOT))) {\n  throw new IllegalStateException(\"sonar.log.level must be one of \" + ALLOWED + \", got: \" + lvl);\n}","typeGuard":null,"tryCatchPattern":"try {\n  Level level = logHelper.getPropertyValueAsLevel(\"sonar.log.level\");\n} catch (IllegalArgumentException e) {\n  logger.error(\"Invalid log level config: {}\", e.getMessage());\n  // fall back to INFO\n}","preventionTips":["Only use TRACE, DEBUG, INFO, WARN, ERROR for SonarQube log levels.","Map other frameworks' level names before writing them into sonar.properties.","Test log-level changes via the web admin UI, which validates values."],"tags":["logging","configuration","enum"],"backgroundTag":"invalid-enum-value","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}