{"record":{"id":"dd3481422cd09d39","repo":"apache/seatunnel","slug":"log-file-path-is-empty-no-log-file-path-configure","errorCode":null,"errorMessage":"Log file path is empty, no log file path configured in the current configuration file","messagePattern":"Log file path is empty, no log file path configured in the current configuration file","errorType":"console","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/servlet/LogBaseServlet.java","lineNumber":53,"sourceCode":"\n    public LogBaseServlet(NodeEngineImpl nodeEngine) {\n        super(nodeEngine);\n    }\n\n    /**\n     * Prepares the servlet log response after enforcing the configured log directory boundary.\n     *\n     * <p>The requested log file is resolved to its canonical path before reading so that relative\n     * segments and symbolic links cannot escape the canonical log directory.\n     *\n     * @param resp response used to return status and log content\n     * @param logPath configured log directory\n     * @param logName requested log file name from the request URI\n     */\n    protected void prepareLogResponse(HttpServletResponse resp, String logPath, String logName) {\n        if (StringUtils.isBlank(logPath)) {\n            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);\n            log.warn(\n                    \"Log file path is empty, no log file path configured in the current configuration file\");\n            return;\n        }\n        String logFilePath = new File(logPath, logName).getPath();\n        try {\n            String canonicalLogDir = new File(logPath).getCanonicalPath();\n            String canonicalFilePath = new File(logFilePath).getCanonicalPath();\n            if (!canonicalFilePath.startsWith(canonicalLogDir + File.separator)\n                    && !canonicalFilePath.equals(canonicalLogDir)) {\n                resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);\n                log.warn(\n                        \"Path traversal attempt blocked - Requested: {}, Resolved: {}, LogDir: {}\",\n                        logName,\n                        canonicalFilePath,\n                        canonicalLogDir);\n                return;\n            }\n            String logContent = FileUtils.readFileToStr(new File(canonicalFilePath).toPath());","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/servlet/LogBaseServlet.java#L35-L71","documentation":"LogBaseServlet.prepareLogResponse guards every log-file request: if the configured logPath is blank it returns HTTP 400 BAD_REQUEST and logs this warning, because no log directory is configured in the current configuration file, so any log name/path request cannot be served.","triggerScenarios":"Any GET to a log-content/log-download endpoint on a node whose logging configuration lacks a file path (blank logPath passed to prepareLogResponse), e.g., console-only logging setup or missing log4j2 file-appender configuration.","commonSituations":"Deployment using console appender only; log4j2.properties/custom config missing the file appender path; env var like SEATUNNEL_HOME unset so derived log path resolves empty; mis-edited config removing the file path.","solutions":["Configure a file appender with an explicit fileName/directory in the node's log4j2 (or chosen logging) configuration and restart.","Set the log path system property/env (e.g., -Dseatunnel.logs.path=...) when launching the node.","Verify with a GET to the log-name endpoint that the path resolves (see errorIndex 3718).","Avoid blank config values; comment removals in logging config can silently blank the path."],"exampleFix":"// before (log4j2.properties, console only, no file appender)\n// rootLogger.appenderRef.stdout.ref = console\n// after\n// appender.file.type = File\n// appender.file.name = file\n// appender.file.fileName = ${sys:seatunnel.logs.path}/seatunnel.log\n// rootLogger.appenderRef.file.ref = file","handlingStrategy":"validation","validationCode":"// before calling log endpoints, verify config\n// String logPath = System.getProperty(\"seatunnel.logs.path\");\n// if (logPath == null || logPath.isBlank()) {\n//     throw new IllegalStateException(\"log path not configured\");\n// }\n// if (!Files.isDirectory(Paths.get(logPath))) { throw ... }","typeGuard":null,"tryCatchPattern":"try {\n    Response r = restGet(\"/log/name\");\n    if (r.status() == 400) { configureLogPath(); }\n} catch (Exception e) { handle(e); }","preventionTips":["Ensure log4j2 config always defines a file appender path","Set -Dseatunnel.logs.path at node startup","Test log endpoints after any logging config edits"],"tags":["servlet","rest-api","logging","configuration","bad-request"],"backgroundTag":"missing-config-value","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}