{"record":{"id":"23190562b293de00","repo":"languagetool-org/languagetool","slug":"dblogging-can-only-be-true-if-dbdriver-dburl-dbu","errorCode":null,"errorMessage":"dbLogging can only be true if dbDriver, dbUrl, dbUsername, and dbPassword are all set","messagePattern":"dbLogging can only be true if dbDriver, dbUrl, dbUsername, and dbPassword are all set","errorType":"console","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"languagetool-server/src/main/java/org/languagetool/server/HTTPServerConfig.java","lineNumber":462,"sourceCode":"\n        gracefulDatabaseFailure = Boolean.parseBoolean(getOptionalProperty(props, \"gracefulDatabaseFailure\", \"false\").trim());\n        dbDriver = getOptionalProperty(props, \"dbDriver\", null);\n        dbUrl = getOptionalProperty(props, \"dbUrl\", null);\n        dbUsername = getOptionalProperty(props, \"dbUsername\", null);\n        dbPassword = getOptionalProperty(props, \"dbPassword\", null);\n        dbTimeoutSeconds = Integer.parseInt(getOptionalProperty(props, \"dbTimeoutSeconds\", \"10\"));\n        dbMaxConnections = Integer.parseInt(getOptionalProperty(props, \"dbMaxConnections\", \"10\"));\n        databaseErrorRateThreshold = Integer.parseInt(getOptionalProperty(props, \"dbErrorRateThreshold\", \"50\"));\n        databaseTimeoutRateThreshold = Integer.parseInt(getOptionalProperty(props, \"dbTimeoutRateThreshold\", \"100\"));\n        databaseDownIntervalSeconds = Integer.parseInt(getOptionalProperty(props, \"dbDownIntervalSeconds\", \"10\"));\n        dbLogging = Boolean.valueOf(getOptionalProperty(props, \"dbLogging\", \"false\").trim());\n        passwortLoginAccessListPath = getOptionalProperty(props, \"passwortLoginAccessListPath\", \"\");\n        prometheusMonitoring = Boolean.valueOf(getOptionalProperty(props, \"prometheusMonitoring\", \"false\").trim());\n        prometheusPort = Integer.parseInt(getOptionalProperty(props, \"prometheusPort\", \"9301\"));\n        skipLoggingRuleMatches = Boolean.valueOf(getOptionalProperty(props, \"skipLoggingRuleMatches\", \"false\").trim());\n        skipLoggingChecks = Boolean.valueOf(getOptionalProperty(props, \"skipLoggingChecks\", \"false\").trim());\n        if (dbLogging && (dbDriver == null || dbUrl == null || dbUsername == null || dbPassword == null)) {\n          throw new IllegalArgumentException(\"dbLogging can only be true if dbDriver, dbUrl, dbUsername, and dbPassword are all set\");\n        }\n        slowRuleLoggingThreshold = Integer.valueOf(getOptionalProperty(props, \"slowRuleLoggingThreshold\", \"-1\"));\n        disabledRuleIds = Arrays.asList(getOptionalProperty(props, \"disabledRuleIds\", \"\").split(\",\\\\s*\"));\n        localApiMode = Boolean.parseBoolean(getOptionalProperty(props, \"localApiMode\", \"false\"));\n        motherTongue = getOptionalProperty(props, \"motherTongue\", \"en-US\");\n        String preferredLanguages = getOptionalProperty(props, \"preferredLanguages\", \"\").replace(\" \", \"\");\n        if (!preferredLanguages.equals(\"\")) {\n          this.preferredLanguages = Arrays.asList(preferredLanguages.split(\",\"));\n        }\n        dictLimitUser = Integer.valueOf(getOptionalProperty(props, \"dictLimitUser\", \"0\"));\n        dictLimitTeam = Integer.valueOf(getOptionalProperty(props, \"dictLimitTeam\", \"0\"));\n        styleGuideLimitUser = Integer.valueOf(getOptionalProperty(props, \"styleGuideLimitUser\", \"0\"));\n        styleGuideLimitTeam = Integer.valueOf(getOptionalProperty(props, \"styleGuideLimitTeam\", \"0\"));\n        requestLimitAccessToken = getOptionalProperty(props, \"requestLimitAccessToken\", null);\n        jwtSecret = getOptionalProperty(props, \"jwtSecret\", null);\n        externalRolloutServiceUrl = getOptionalProperty(props, \"externalRolloutServiceUrl\", null);\n        externalRolloutServiceApiKey = getOptionalProperty(props, \"externalRolloutServiceApiKey\", null);\n","sourceCodeStart":444,"sourceCodeEnd":480,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-server/src/main/java/org/languagetool/server/HTTPServerConfig.java#L444-L480","documentation":"When 'dbLogging=true' the server logs rule matches to a database, which requires complete JDBC connection settings: dbDriver, dbUrl, dbUsername, and dbPassword. If any of these is null, HTTPServerConfig throws this IllegalArgumentException because logging to the DB would fail.","triggerScenarios":"Server properties file contains 'dbLogging=true' but is missing one or more of dbDriver, dbUrl, dbUsername, or dbPassword.","commonSituations":"Credentials omitted from the config for security but not injected via environment/template; partial config copied from another environment; dbDriver/dbUrl forgotten while only user/password set.","solutions":["Set all four properties: dbDriver (e.g. com.mysql.cj.jdbc.Driver), dbUrl, dbUsername, dbPassword","Inject the missing values at deploy time via environment-variable substitution in the properties template","Set 'dbLogging=false' if database logging is not actually needed"],"exampleFix":"// before (server.properties)\ndbLogging=true\ndbUrl=jdbc:mysql://localhost/ltlogs\n\n// after (server.properties)\ndbLogging=true\ndbDriver=com.mysql.cj.jdbc.Driver\ndbUrl=jdbc:mysql://localhost/ltlogs\ndbUsername=ltuser\ndbPassword=secret","handlingStrategy":"validation","validationCode":"if (Boolean.parseBoolean(props.getProperty(\"dbLogging\", \"false\"))) {\n    for (String k : new String[]{\"dbDriver\", \"dbUrl\", \"dbUsername\", \"dbPassword\"}) {\n        if (props.getProperty(k) == null) throw new IllegalStateException(\"dbLogging=true requires \" + k);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    serverConfig = new HTTPServerConfig(props);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"dbLogging can only be true\")) {\n        log.error(\"Incomplete DB config; check dbDriver/dbUrl/dbUsername/dbPassword\");\n    }\n    throw e;\n}","preventionTips":["Inject DB credentials via environment-variable placeholders in the properties template","Keep db settings together in one config block so none are dropped","Set dbLogging=false by default and enable it only with a complete DB section"],"tags":["java","languagetool","database","logging","server-config"],"backgroundTag":"missing-required-config-field","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}