mybatis/mybatis-3 · error · BuilderException
Mapper's namespace cannot be empty
Error message
Mapper's namespace cannot be empty
What it means
Thrown by XMLMapperBuilder.configurationElement() when the <mapper> root element of a mapper XML file has no namespace attribute or an empty one. The namespace is the mapper's identity: it binds the XML to a Java interface and prefixes every statement id, fragment id and cache-ref, so an empty namespace is fatal. Note this is usually re-wrapped as 'Error parsing Mapper XML' (error 67) with this as the cause.
Source
Thrown at src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java:122
if (!configuration.isResourceLoaded(resource)) {
configurationElement(parser.evalNode("/mapper"));
configuration.addLoadedResource(resource);
bindMapperForNamespace();
}
configuration.parsePendingResultMaps(false);
configuration.parsePendingCacheRefs(false);
configuration.parsePendingStatements(false);
}
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);View on GitHub (pinned to 008069adb1)
Solutions
- Set namespace to the fully-qualified name of the corresponding mapper interface, e.g. <mapper namespace="com.acme.UserMapper">
- Ensure the interface exists and its package/name match the namespace exactly (case-sensitive)
- If the mapper is XML-only with no interface, you still need a unique non-empty namespace string
Example fix
<!-- before --> <mapper> <select id="findById" resultType="User">...</select> </mapper> <!-- after --> <mapper namespace="com.acme.UserMapper"> <select id="findById" resultType="User">...</select> </mapper>
Defensive patterns
Strategy: validation
Validate before calling
String ns = mapperRoot.getAttribute("namespace");
if (ns == null || ns.trim().isEmpty()) throw new IllegalStateException("mapper XML missing namespace");
if (!ns.matches("(?:[a-zA-Z_$][\\w$]*\\.)+[a-zA-Z_$][\\w$]*")) warn("namespace looks unlike an FQCN: " + ns); Try / catch
catch BuilderException at build and surface the resource path; a missing namespace is a build-time fix, not a runtime recovery.
Prevention
- Generate mapper XML from IDE templates that prefill the namespace
- Enforce namespace == mapper interface FQCN in a CI check
When it happens
Trigger: <mapper> without a namespace attribute: <mapper>...</mapper>; or namespace="" (empty string). Raised when the mapper XML is parsed, whether loaded via <mapper resource=...>, url, or automatically alongside an interface.
Common situations: New hand-written mapper XML from a blank template; trimming the file and deleting the root element's attributes; namespace typed as a path (slashes) or with leading/trailing whitespace-only content; mapper XML placed in the same package as the interface but with missing namespace during annotation+XML mixed setups.
Related errors
- The mapper element requires a namespace attribute to be spec
- Wrong namespace. Expected '{currentNamespace}' but found '{c
- Could not find SQL statement to include with refid '{refid}'
- Variable {name} defined twice in the same include definition
- Error parsing Mapper XML. The XML location is '{resource}'.
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/1c2d9ef386969f9a.
Report an issue: GitHub.