{"record":{"id":"62593fc1655fa547","repo":"jenkinsci/jenkins","slug":"failed-to-fully-read-0","errorCode":null,"errorMessage":"Failed to fully read {0}","messagePattern":"Failed to fully read (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/hudson/Util.java","lineNumber":279,"sourceCode":"        // One approach that cannot be used is Files.newBufferedReader, which\n        // creates its CharsetDecoder with the default behavior of reporting\n        // malformed input and unmappable character errors. The implementation\n        // of InputStreamReader(InputStream, Charset) has the desired behavior\n        // of replacing malformed input and unmappable character errors, but\n        // this implementation is not specified in the API contract. Therefore,\n        // we explicitly use a decoder with the desired behavior.\n        // See: https://issues.jenkins.io/browse/JENKINS-49060?focusedCommentId=325989&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-325989\n        CharsetDecoder decoder = charset.newDecoder()\n                .onMalformedInput(CodingErrorAction.REPLACE)\n                .onUnmappableCharacter(CodingErrorAction.REPLACE);\n        try (InputStream is = Files.newInputStream(Util.fileToPath(logfile));\n                Reader isr = new InputStreamReader(is, decoder);\n                Reader br = new BufferedReader(isr)) {\n            return IOUtils.toString(br);\n        } catch (NoSuchFileException e) {\n            return \"\";\n        } catch (Exception e) {\n            throw new IOException(\"Failed to fully read \" + logfile, e);\n        }\n    }\n\n    /**\n     * Deletes the contents of the given directory (but not the directory itself)\n     * recursively.\n     * It does not take no for an answer - if necessary, it will have multiple\n     * attempts at deleting things.\n     *\n     * @throws IOException\n     *      if the operation fails.\n     */\n    public static void deleteContentsRecursive(@NonNull File file) throws IOException {\n        deleteContentsRecursive(fileToPath(file), PathRemover.PathChecker.ALLOW_ALL);\n    }\n\n    /**\n     * Deletes the given directory contents (but not the directory itself) recursively using a PathChecker.","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/jenkinsci/jenkins/blob/2e228ff40b14dbc8b14ffbc6edf0e4383cf744fc/core/src/main/java/hudson/Util.java#L261-L297","documentation":"Wraps any exception (other than NoSuchFileException, which returns an empty string) encountered while reading a log file to a String using a forgiving CharsetDecoder (REPLACE on malformed/unmappable). The file is opened via Files.newInputStream, wrapped in InputStreamReader with the decoder, then BufferedReader, and read with IOUtils.toString.","triggerScenarios":"Any exception in the try-with-resources chain that is not NoSuchFileException — this includes IOException from Files.newInputStream (permission denied, broken symlink), IOException from the Reader, or any other Exception subclass. The original exception is attached as the cause.","commonSituations":"Log file exists but is not readable due to filesystem permissions (e.g., owned by a different user); file is a broken symlink; disk I/O error or filesystem corruption; file was deleted between the call and the actual open (race condition that slips past NoSuchFileException check); NFS/network filesystem hiccup.","solutions":["Check the cause exception (getCause()) for the specific I/O failure type and message.","Verify file permissions: the Jenkins user must have read access to the log file path.","If the path is a symlink, verify the target exists and is readable.","For network filesystems, ensure the mount is healthy and not stale.","If the file is being actively rotated, consider retrying or handling the transient failure."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Validate file readability before calling Util.loadLog\nif (logfile != null) {\n    Path p = Util.fileToPath(logfile);\n    if (!Files.isReadable(p)) {\n        return \"\"; // or handle accordingly\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    String content = Util.loadLogFile(logfile, charset);\n} catch (IOException e) {\n    // getCause() has the specific failure\n    if (e.getCause() instanceof AccessDeniedException) {\n        LOGGER.warning(\"Log file not readable: \" + logfile + \" — check permissions\");\n    } else {\n        LOGGER.log(Level.WARNING, \"Failed to read log file: \" + logfile, e);\n    }\n    return \"\"; // graceful degradation\n}","preventionTips":["Ensure the Jenkins process user owns or has read access to log file directories.","Avoid symlinks to network filesystems that may become stale.","Use atomic writes or rotation-safe log access patterns to avoid race conditions."],"tags":["filesystem","io","logging","permissions"],"backgroundTag":null,"analyzedSha":"2e228ff40b14dbc8b14ffbc6edf0e4383cf744fc","analyzedAt":"2026-08-14T07:07:15.274Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}