baomidou/mybatis-plus · critical · IOException
Failed to parse mapping resource: '
Error message
Failed to parse mapping resource: '
What it means
Thrown by MybatisSqlSessionFactoryBean.buildSqlSessionFactory while iterating mapperLocations: if MybatisXMLMapperBuilder.parse() throws for any mapper XML resource, it is wrapped in IOException('Failed to parse mapping resource: \'' + mapperLocation + '\''). The resource path in the message identifies which mapper file failed; the cause holds the parser detail (bad statement id, duplicate mapping, invalid SQL node, missing result map, etc.).
Source
Thrown at mybatis-plus-spring/src/main/java/com/baomidou/mybatisplus/spring/MybatisSqlSessionFactoryBean.java:684
targetConfiguration.setEnvironment(new Environment(this.environment,
this.transactionFactory == null ? new SpringManagedTransactionFactory() : this.transactionFactory,
this.dataSource));
if (this.mapperLocations != null) {
if (this.mapperLocations.length == 0) {
LOGGER.warn(() -> "Property 'mapperLocations' was specified but matching resources are not found.");
} else {
for (Resource mapperLocation : this.mapperLocations) {
if (mapperLocation == null) {
continue;
}
try {
MybatisXMLMapperBuilder xmlMapperBuilder = new MybatisXMLMapperBuilder(mapperLocation.getInputStream(),
targetConfiguration, mapperLocation.toString(), targetConfiguration.getSqlFragments());
xmlMapperBuilder.parse();
} catch (Exception e) {
throw new IOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);
} finally {
ErrorContext.instance().reset();
}
LOGGER.debug(() -> "Parsed mapper file: '" + mapperLocation + "'");
}
}
} else {
LOGGER.debug(() -> "Property 'mapperLocations' was not specified.");
}
final SqlSessionFactory sqlSessionFactory = this.sqlSessionFactoryBuilder.build(targetConfiguration);
SqlHelper.FACTORY = sqlSessionFactory;
if (globalConfig.isBanner()) {
System.out.println(" _ _ |_ _ _|_. ___ _ | _ ");
System.out.println("| | |\\/|_)(_| | |_\\ |_)||_|_\\ ");
System.out.println(" / | ");View on GitHub (pinned to bf67d90747)
Solutions
- Open the mapper file named in the message and fix the issue described by the cause exception (duplicate id, invalid attribute, malformed XML)
- Run xmllint or IDE validation on all files matched by the mapperLocations pattern to catch sibling errors in the same pass
- Verify every <include refid=...> has a matching <sql id=...> in the same namespace (or imported namespace)
- Tighten the mapperLocations pattern if it is matching non-mapper XML files
Example fix
<!-- before: duplicate statement id in namespace --> <select id="selectUser" resultType="User">SELECT * FROM user</select> <select id="selectUser" resultType="User">SELECT * FROM users</select> <!-- after --> <select id="selectUser" resultType="User">SELECT * FROM user</select> <select id="selectUsers" resultType="User">SELECT * FROM users</select>
Defensive patterns
Strategy: validation
Validate before calling
// Validate every mapper XML is well-formed and has unique statement ids before startup
for (Resource r : ctx.getResources("classpath*:mapper/**/*.xml")) {
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(r.getInputStream());
// additionally parse with XPath: collect select|insert|update|delete @id per namespace and assert uniqueness
} Try / catch
try {
factory.getObject();
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Failed to parse mapping resource:")) {
String file = e.getMessage().substring(e.getMessage().indexOf('\''));
throw new IllegalStateException("Broken mapper XML " + file + ": " + e.getCause().getMessage(), e.getCause());
}
throw e;
} Prevention
- Run xmllint over mapper/**/*.xml in CI
- Assert unique statement ids per namespace in a build-time check
- After refactors, grep for <include refid> targets to confirm they still exist
When it happens
Trigger: Configuring mapperLocations (e.g. classpath*:mapper/**/*.xml) where at least one file is invalid: unparseable XML, a <select> without a resultType/resultMap or a duplicate id within the namespace, a <include> referencing a missing sql fragment, or OGNL/#{} syntax errors.
Common situations: Merge conflicts leaving broken XML; refactoring mapper namespaces or statement ids and forgetting references; adding a new mapper with a duplicated id; empty mapper XML with wrong root element; resource patterns (classpath*: vs classpath:) pulling in unexpected files.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to parse config resource:
- Failed getting a databaseId
- %s already contains value for %s
- %s does not contain value for %s
- %s is ambiguous in %s (try using the full name including the
AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14).
Data as JSON: /api/errors/3c9c56fd8aa26cd2.
Report an issue: GitHub.