mybatis/mybatis-3 · error · BuilderException

Error parsing Mapper XML. The XML location is '{resource}'.

Error message

Error parsing Mapper XML. The XML location is '{resource}'. Cause: {cause}

What it means

Catch-all thrown by XMLMapperBuilder.configurationElement(): any exception raised while parsing the body of a mapper XML (namespace, cache-ref, cache, parameterMap, resultMap, sql fragments, statements) is re-thrown with this message including the resource path and the original cause. It is a wrapper — the real problem is always in the 'Cause:' part and the nested exception, never in this message itself.

Source

Thrown at src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java:132

  public XNode getSqlFragment(String refid) {
    return sqlFragments.get(refid);
  }

  private void configurationElement(XNode context) {
    try {
      String namespace = context.getStringAttribute("namespace");
      if (namespace == null || namespace.isEmpty()) {
        throw new BuilderException("Mapper's namespace cannot be empty");
      }
      builderAssistant.setCurrentNamespace(namespace);
      cacheRefElement(context.evalNode("cache-ref"));
      cacheElement(context.evalNode("cache"));
      parameterMapElement(context.evalNodes("/mapper/parameterMap"));
      resultMapElements(context.evalNodes("/mapper/resultMap"));
      sqlElement(context.evalNodes("/mapper/sql"));
      buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing Mapper XML. The XML location is '" + resource + "'. Cause: " + e, e);
    }
  }

  private void buildStatementFromContext(List<XNode> list) {
    if (configuration.getDatabaseId() != null) {
      buildStatementFromContext(list, configuration.getDatabaseId());
    }
    buildStatementFromContext(list, null);
  }

  private void buildStatementFromContext(List<XNode> list, String requiredDatabaseId) {
    for (XNode context : list) {
      final XMLStatementBuilder statementParser = new XMLStatementBuilder(configuration, builderAssistant, context,
          requiredDatabaseId, mapperClass);
      try {
        statementParser.parseStatementNode();
      } catch (IncompleteElementException e) {
        configuration.addIncompleteStatement(statementParser);

View on GitHub (pinned to 008069adb1)

Solutions

  1. Read the 'Cause: ' suffix and the nested exception stack — fix that root cause, not this wrapper
  2. Verify the resource path printed in the message matches the file you think you are editing (stale jars and duplicate copies on the classpath are common)
  3. After fixing, rebuild/repackage so the deployed jar contains the corrected XML

Example fix

// before: error Cause: BuilderException: Mapper's namespace cannot be empty
<mapper>...</mapper>

// after
<mapper namespace="com.acme.UserMapper">...</mapper>
Defensive patterns

Strategy: try-catch

Validate before calling

// CI: build the factory to fail fast
new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));

Try / catch

try { sqlSessionFactory = builder.build(config); } catch (BuilderException e) { log.error("mapper parse failed: {} cause={}", e.getMessage(), e.getCause()); throw e; } — always unwrap the Cause to find the real error.

Prevention

When it happens

Trigger: Any malformed mapper content: empty namespace (error 66), invalid resultMap, unsupported JDBC type, bad attribute on a statement, class-not-found for a resultType/parameterType, invalid OGNL/cache-ref reference — anything inside configurationElement() that throws during XMLMapperBuilder.parse().

Common situations: Every mapper-level configuration mistake surfaces here, so this is the most common mybatis startup error after XML syntax errors; frequent after upgrades where attribute names or defaults changed, or when a referenced type is missing from the classpath in a packaged jar.

Related errors


AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14). Data as JSON: /api/errors/29addce7972e3a90. Report an issue: GitHub.