apache/pulsar · error · IllegalArgumentException

Could not open configuration file

Error message

Could not open configuration file

What it means

PulsarBrokerStarter.readBookieConfFile loads the Bookie configuration file when the broker runs a bookie or bookie auto-recovery in the same process. A MalformedURLException while converting the file path to a URL (i.e. the file cannot be opened/resolved as a URL) is logged and rethrown as this IllegalArgumentException.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/PulsarBrokerStarter.java:117

        @Option(names = {"-fwc", "--functions-worker-conf"}, description = "Configuration file for Functions Worker")
        private String fnWorkerConfigFile = "conf/functions_worker.yml";

        @Option(names = {"-h", "--help"}, usageHelp = true, description = "Show this help message")
        private boolean help = false;

        @Option(names = {"-g", "--generate-docs"}, description = "Generate docs")
        private boolean generateDocs = false;
    }

    private static ServerConfiguration readBookieConfFile(String bookieConfigFile) throws IllegalArgumentException {
        ServerConfiguration bookieConf = new ServerConfiguration();
        try {
            bookieConf.loadConf(new File(bookieConfigFile).toURI().toURL());
            bookieConf.validate();
            log.info().attr("file", bookieConfigFile).log("Using bookie configuration file");
        } catch (MalformedURLException e) {
            log.error().attr("file", bookieConfigFile).exception(e).log("Could not open configuration file");
            throw new IllegalArgumentException("Could not open configuration file");
        } catch (ConfigurationException e) {
            log.error().attr("file", bookieConfigFile).exception(e).log("Malformed configuration file");
            throw new IllegalArgumentException("Malformed configuration file");
        }

        if (bookieConf.getMaxPendingReadRequestPerThread() < bookieConf.getRereplicationEntryBatchSize()) {
            throw new IllegalArgumentException(
                "rereplicationEntryBatchSize should be smaller than " + "maxPendingReadRequestPerThread");
        }
        return bookieConf;
    }

    protected static class BrokerStarter implements Callable<Integer> {
        private ServiceConfiguration brokerConfig;
        private PulsarService pulsarService;
        private LifecycleComponent bookieServer;
        private volatile CompletableFuture<Void> bookieStartFuture;
        private AutoRecoveryMain autoRecoveryMain;

View on GitHub (pinned to 820761864e)

Solutions

  1. Pass a valid, existing bookie configuration file path via --bookie-config/-bc
  2. Verify the file exists and is readable by the broker user (run ls on the path)
  3. Use an absolute path to avoid working-directory ambiguity

Example fix

// before
./pulsar broker --bookie-config conf/bookie.conf
// after
./pulsar broker --bookie-config /pulsar/conf/bookie.conf
Defensive patterns

Strategy: validation

Validate before calling

Path p = Paths.get(args.bookieConfigFile);
if (args.bookieConfigFile == null || !Files.isRegularFile(p) || !Files.isReadable(p)) {
    throw new IllegalArgumentException("Bookie config not a readable file: " + p);
}

Try / catch

try {
    BookKeeperConfiguration conf = readBookieConfFile(bookieConfigFile);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Could not open")) {
        throw new IllegalStateException("Check --bookie-config path: " + bookieConfigFile, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Passing -bc/--bookieConfigFile whose path is malformed or unreadable; bookieConf.loadConf(new File(bookieConfigFile).toURI().toURL()) throws MalformedURLException.

Common situations: Typo in the --bookie-config path; file missing; using a directory instead of a file; relative path resolved against an unexpected working directory.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/c88073583fbffe80. Report an issue: GitHub.