nathanmarz/storm · error · RuntimeException

Could not find config file on classpath

Error message

Could not find config file on classpath ${name}

What it means

Utils.findAndReadConfigFile loads a YAML config resource from the classpath; when mustExist is true and findResources(name) returns nothing, it throws RuntimeException stating the config file could not be found on the classpath. Callers like readDefaultConfig and readStormConfig always require the file, so a missing default.yaml/storm.yaml resource is fatal.

Solutions

  1. Put storm.yaml on the classpath (usually in ~/.storm or passed via -Dstorm.conf.file / STORM_CONF_DIR) before running.
  2. Verify the file name passed to findAndReadConfigFile matches an existing classpath resource exactly (case-sensitive, with extension).
  3. Check the topology/uber jar isn't excluding *.yaml via build filters, or that you're not shading Storm out of the classpath.
  4. If the file is genuinely optional, call findAndReadConfigFile(name, false) which returns an empty Map instead of throwing.

Example fix

// before
Map conf = Utils.findAndReadConfigFile("storm.yaml", true);
// after
Map conf = Utils.findConfigFile("storm.yaml") != null
    ? Utils.findAndReadConfigFile("storm.yaml", true)
    : new HashMap();  // or fix classpath so storm.yaml is present
Defensive patterns

Strategy: try-catch

Validate before calling

if (Utils.findResources("storm.yaml").isEmpty()) {
    throw new IllegalStateException("storm.yaml not on classpath; set STORM_CONF_DIR or -Dstorm.conf.file");
}

Try / catch

try {
    conf = Utils.readStormConfig();
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("Could not find config file")) {
        conf = new HashMap();  // fall back to defaults and warn
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling Utils.findAndReadConfigFile(name, true) — directly or via readDefaultConfig()/readStormConfig() — when no classpath resource matches name (e.g. storm.yaml not present on the classpath, or default.yaml absent because the Storm jar is incomplete).

Common situations: Running a topology locally without storm.yaml on the classpath; packaging a topology jar that excludes Storm's config resources; wrong working directory/classloader so the resource isn't visible; typo in the config file name.

Understand the failure class

Background: "Config file not found": what it means and how to fix it in docker-sync, Maven, Vagrant, Turborepo and other tools — this error's family across 60 libraries.

Related errors


AI-assisted analysis of nathanmarz/storm@cdb116e942 (2026-09-12). Data as JSON: /api/errors/b787a6ac6fcef14a. Report an issue: GitHub.

Appendix: source

Thrown at storm-core/src/jvm/backtype/storm/utils/Utils.java:129

    
    public static List<URL> findResources(String name) {
        try {
            Enumeration<URL> resources = Thread.currentThread().getContextClassLoader().getResources(name);
            List<URL> ret = new ArrayList<URL>();
            while(resources.hasMoreElements()) {
                ret.add(resources.nextElement());
            }
            return ret;
        } catch(IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static Map findAndReadConfigFile(String name, boolean mustExist) {
        try {
            HashSet<URL> resources = new HashSet<URL>(findResources(name));
            if(resources.isEmpty()) {
                if(mustExist) throw new RuntimeException("Could not find config file on classpath " + name);
                else return new HashMap();
            }
            if(resources.size() > 1) {
                throw new RuntimeException("Found multiple " + name + " resources. You're probably bundling the Storm jars with your topology jar. "
                  + resources);
            }
            URL resource = resources.iterator().next();
            Yaml yaml = new Yaml();
            Map ret = (Map) yaml.load(new InputStreamReader(resource.openStream()));
            if(ret==null) ret = new HashMap();
            

            return new HashMap(ret);
            
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

View on GitHub (pinned to cdb116e942)