{"id":"8e0f1e1f8f603718","repo":"spring-projects/spring-boot","slug":"failed-to-load-layers-configuration-with-name-s","errorCode":null,"errorMessage":"Failed to load layers configuration with name '%s': '%s' not found","messagePattern":"Failed to load layers configuration with name '(.+?)': '(.+?)' not found","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java","lineNumber":215,"sourceCode":"\t}\n\n\tprivate org.springframework.boot.loader.tools.Layers loadLayersConfiguration() {\n\t\tFile configuration = this.layers.getConfiguration();\n\t\tif (configuration != null) {\n\t\t\treturn getCustomLayers(configuration.getAbsolutePath(), () -> new FileInputStream(configuration));\n\t\t}\n\t\tString configurationName = this.layers.getConfigurationName();\n\t\tif (configurationName != null) {\n\t\t\tString location = \"META-INF/spring/layers/%s.xml\".formatted(configurationName);\n\t\t\treturn getCustomLayers(location, () -> loadLayersConfigurationFromClasspath(configurationName, location));\n\t\t}\n\t\treturn IMPLICIT_LAYERS;\n\t}\n\n\tprivate InputStream loadLayersConfigurationFromClasspath(String name, String location) {\n\t\tInputStream in = this.pluginDescriptor.getClassRealm().getResourceAsStream(location);\n\t\tif (in == null) {\n\t\t\tthrow new IllegalStateException(\n\t\t\t\t\t\"Failed to load layers configuration with name '%s': '%s' not found\".formatted(name, location));\n\t\t}\n\t\treturn in;\n\t}\n\n\tprivate CustomLayers getCustomLayers(String source, InputStreamSource inputStreamSource) {\n\t\ttry {\n\t\t\tDocument document = getDocumentIfAvailable(inputStreamSource);\n\t\t\treturn new CustomLayersProvider().getLayers(document);\n\t\t}\n\t\tcatch (Exception ex) {\n\t\t\tthrow new IllegalStateException(\"Failed to process custom layers configuration \" + source, ex);\n\t\t}\n\t}\n\n\tprivate Document getDocumentIfAvailable(InputStreamSource source) throws Exception {\n\t\ttry (InputStream in = source.getInputStream()) {\n\t\t\tInputSource inputSource = new InputSource(in);","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/spring-projects/spring-boot/blob/5b2dbdbb8be64415eb6552f81ff7c449c8d251e6/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java#L197-L233","documentation":"Thrown by AbstractPackagerMojo.loadLayersConfigurationFromClasspath when a custom layers configuration is requested by name (via <layers><configurationName>...</configurationName></layers>) but the resource META-INF/spring/layers/<name>.xml cannot be found on the plugin's class realm. The plugin resolves named configurations as classpath resources rather than filesystem paths, so a missing resource means the name is wrong or the contributing module did not place the XML correctly. It surfaces as an IllegalStateException during packager configuration.","triggerScenarios":"Setting <layers><configurationName>my-layers</configurationName></layers> in the repackage/build-image configuration when no META-INF/spring/layers/my-layers.xml exists on the plugin classpath. Also triggered if a multi-module build expects a sibling module to contribute the layers.xml via a dependency but that dependency is not on the plugin class realm.","commonSituations":"Typo in the configurationName; placing the layers.xml under src/main/resources of the application module instead of a dependency that the plugin resolves; upgrading a project that previously used a <configuration> file path and migrating to the named form incorrectly; relying on a library that was supposed to ship the layers.xml but the dependency was marked optional or excluded.","solutions":["Verify the exact value of <configurationName> matches the file basename under META-INF/spring/layers/.","Confirm the module or dependency that ships META-INF/spring/layers/<name>.xml is a normal (non-optional, non-excluded) dependency resolvable from the plugin class realm.","If you intended a filesystem path instead of a classpath name, use <layers><configuration>/path/to/layers.xml</configuration></layers> instead of configurationName.","Inspect the built jar (unzip -l) to confirm the layers.xml is actually packaged at META-INF/spring/layers/."],"exampleFix":"// before (pom.xml)\n<layers>\n  <configurationName>mylayers</configurationName>\n</layers>\n// after (match the shipped file name META-INF/spring/layers/my-layers.xml)\n<layers>\n  <configurationName>my-layers</configurationName>\n</layers>","handlingStrategy":"validation","validationCode":"// Before configuring, confirm the classpath resource exists in the built jar\nimport java.io.IOException;\nimport java.util.jar.JarFile;\n\nboolean layersResourceExists(File jar, String configurationName) throws IOException {\n    String entry = \"META-INF/spring/layers/\" + configurationName + \".xml\";\n    try (JarFile jf = new JarFile(jar)) {\n        return jf.getEntry(entry) != null;\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat <configurationName> as a classpath contract: ship the layers.xml at META-INF/spring/layers/ in a real (non-optional) dependency.","Use a CI step that asserts the expected layers.xml resource is present in the published artifact.","Prefer the <configuration> file-path form during local iteration to avoid classpath surprises, and switch to configurationName only when shipping shared configs."],"tags":["maven","layers","configuration","classpath","spring-boot"],"analyzedSha":"5b2dbdbb8be64415eb6552f81ff7c449c8d251e6","analyzedAt":"2026-08-04T18:53:14.967Z","schemaVersion":2}