{"record":{"id":"f211f0bbe00c1c44","repo":"languagetool-org/languagetool","slug":"could-not-load-properties-from-f211f0","errorCode":null,"errorMessage":"Could not load properties from ''","messagePattern":"Could not load properties from ''","errorType":"console","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"languagetool-server/src/main/java/org/languagetool/server/HTTPServerConfig.java","lineNumber":522,"sourceCode":"        }\n\n        addDynamicLanguages(props);\n        setAbTest(getOptionalProperty(props, \"abTest\", null));\n        setAbTestClients(getOptionalProperty(props, \"abTestClients\", null));\n        setAbTestRollout(Integer.parseInt(getOptionalProperty(props, \"abTestRollout\", \"100\")));\n        String ngramLangIdentData = getOptionalProperty(props, \"ngramLangIdentData\", null);\n        setDefaultThirdPartyAI(Boolean.parseBoolean(getOptionalProperty(props, \"defaultThirdPartyAI\", \"false\")));\n\n        if (ngramLangIdentData != null) {\n          File dir = new File(ngramLangIdentData);\n          if (!dir.exists() || dir.isDirectory()) {\n            throw new IllegalArgumentException(\"ngramLangIdentData does not exist or is a directory (needs to be a ZIP file): \" + ngramLangIdentData);\n          }\n          setNgramLangIdentData(dir);\n        }\n      }\n    } catch (IOException e) {\n      throw new RuntimeException(\"Could not load properties from '\" + file + \"'\", e);\n    }\n  }\n\n  private void addDynamicLanguages(Properties props) throws IOException {\n    for (Object keyObj : props.keySet()) {\n      String key = (String)keyObj;\n      if (key.startsWith(\"lang-\") && !key.contains(\"-dictPath\")) {\n        String code = key.substring(\"lang-\".length());\n        if (!code.contains(\"-\") && code.length() != 2 && code.length() != 3) {\n          throw new IllegalArgumentException(\"code is supposed to be a 2 (or rarely 3) character code (unless it uses a format with variant, like xx-YY): '\" + code + \"'\");\n        }\n        String nameKey = \"lang-\" + code;\n        String name = props.getProperty(nameKey);\n        String dictPathKey = \"lang-\" + code + \"-dictPath\";\n        String dictPath = props.getProperty(dictPathKey);\n        if (dictPath == null) {\n          throw new IllegalArgumentException(dictPathKey + \" must be set\");\n        }","sourceCodeStart":504,"sourceCodeEnd":540,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-server/src/main/java/org/languagetool/server/HTTPServerConfig.java#L504-L540","documentation":"HTTPServerConfig loads the server's Properties object from the configured properties file. If reading that file throws an IOException, it is rethrown as a RuntimeException 'Could not load properties from <file>' with the original IOException as the cause, so startup fails loudly.","triggerScenarios":"The properties file passed to the server (e.g. via --config or the standard server.properties location) is missing, unreadable (permissions), or fails during read (I/O error while loading).","commonSituations":"Wrong --config path on the command line; file permissions deny the server user access; file deleted between check and start; Docker secret not mounted.","solutions":["Check the file path passed to the server config option and correct it","Verify read permissions for the user running the LanguageTool server (ls -l, chmod/chown)","Inspect the wrapped IOException (the 'Caused by' of the RuntimeException) for the precise cause (FileNotFoundException vs access denied)","If running in Docker/K8s, ensure the config file is mounted and the mount path matches the config argument"],"exampleFix":"// before\njava -cp languagetool-server.jar org.languagetool.server.HTTPServer --config ./server.propertis --port 8081\n\n// after (correct filename)\njava -cp languagetool-server.jar org.languagetool.server.HTTPServer --config /etc/languagetool/server.properties --port 8081","handlingStrategy":"try-catch","validationCode":"File cfg = new File(configPath);\nif (!cfg.isFile() || !cfg.canRead()) throw new IllegalStateException(\"Cannot read config file: \" + configPath);","typeGuard":null,"tryCatchPattern":"try {\n    serverConfig = new HTTPServerConfig(file);\n} catch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"Could not load properties from\")) {\n        log.error(\"Config file unreadable: {}. Cause: {}\", e.getMessage(), e.getCause());\n    }\n    throw e;\n}","preventionTips":["Verify the --config path and file readability in the startup script before launching the JVM","Print/log e.getCause() to distinguish missing file vs permission vs I/O errors","Check config file presence and permissions in container entrypoints and health checks"],"tags":["java","languagetool","file-read","server-config","io"],"backgroundTag":"file-read-failed","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"}