pinpoint-apm/pinpoint · warning · RuntimeException

banner IO failed

Error message

banner IO failed

What it means

BannerSupplier.readLines loads a banner resource from the classpath and, on IOException, wraps it in a RuntimeException with the message 'banner IO failed'. This turns a non-fatal cosmetic failure (printing the startup banner) into an exception that propagates to the caller.

Source

Thrown at banner/src/main/java/com/navercorp/pinpoint/banner/BannerSupplier.java:34

    public BannerSupplier(String file) {
        this.file = Objects.requireNonNull(file, "file");
    }

    public String get() {
        return banner(file);
    }

    private String banner(String bannerFile) {
        List<String> lines = readLines(bannerFile);
        return writeBanner(lines);
    }

    private List<String> readLines(String bannerFile) {
        try (InputStream inputStream = getClass().getResourceAsStream(bannerFile)) {
            return BannerIOUtils.readLines(inputStream, StandardCharsets.UTF_8);
        } catch (IOException e) {
            throw new RuntimeException("banner IO failed", e);
        }
    }

    private String writeBanner(List<String> lines) {
        String lineSeparator = System.lineSeparator();

        StringBuilder buffer = new StringBuilder(64);
        for (String line : lines) {
            buffer.append(line);
            buffer.append(lineSeparator);
        }
        return buffer.toString();
    }
}

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Verify the banner resource exists on the classpath at the expected path
  2. Rebuild/repackage the artifact so the banner file is included
  3. Catch or tolerate the RuntimeException at the banner-print call site since it is cosmetic
Defensive patterns

Strategy: try-catch

Validate before calling

InputStream in = getClass().getResourceAsStream(bannerFile);
if (in == null) { return Collections.emptyList(); }

Try / catch

try { banner.print(); } catch (RuntimeException e) { log.debug("banner skipped: {}", e.getMessage()); }

Prevention

When it happens

Trigger: getClass().getResourceAsStream(bannerFile) returns a stream that fails to read, or BannerIOUtils.readLines throws IOException while reading the banner resource (resource present but unreadable/corrupt stream).

Common situations: Banner resource missing from a repackaged jar (leading to NPE stream in some paths) or I/O issues in exotic classloader environments; typically seen during application startup.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/c35c35b076a3eb16. Report an issue: GitHub.