alibaba/canal · error · CanalParseException
Unknown host
Error message
Unknown host
What it means
generateUniqueServerId() calls InetAddress.getLocalHost(); if the host's name cannot be resolved to an address, the JVM throws UnknownHostException and canal wraps it in CanalParseException("Unknown host"). The server id is derived from the local host IP bytes, so host resolution is mandatory when slaveId is not explicitly set.
Source
Thrown at parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/MysqlEventParser.java:336
private final long generateUniqueServerId() {
try {
// a=`echo $masterip|cut -d\. -f1`
// b=`echo $masterip|cut -d\. -f2`
// c=`echo $masterip|cut -d\. -f3`
// d=`echo $masterip|cut -d\. -f4`
// #server_id=`expr $a \* 256 \* 256 \* 256 + $b \* 256 \* 256 + $c
// \* 256 + $d `
// #server_id=$b$c$d
// server_id=`expr $b \* 256 \* 256 + $c \* 256 + $d `
InetAddress localHost = InetAddress.getLocalHost();
byte[] addr = localHost.getAddress();
int salt = (destination != null) ? destination.hashCode() : 0;
return ((0x7f & salt) << 24) + ((0xff & (int) addr[1]) << 16) // NL
+ ((0xff & (int) addr[2]) << 8) // NL
+ (0xff & (int) addr[3]);
} catch (UnknownHostException e) {
throw new CanalParseException("Unknown host", e);
}
}
protected EntryPosition findStartPosition(ErosaConnection connection) throws IOException {
if (isGTIDMode()) {
// GTID模式下,CanalLogPositionManager里取最后的gtid,没有则取instance配置中的
LogPosition logPosition = getLogPositionManager().getLatestIndexBy(destination);
if (logPosition != null) {
// 如果以前是非GTID模式,后来调整为了GTID模式,那么为了保持兼容,需要判断gtid是否为空
if (StringUtils.isNotEmpty(logPosition.getPostion().getGtid())) {
return logPosition.getPostion();
}
} else {
if (masterPosition != null && StringUtils.isNotEmpty(masterPosition.getGtid())) {
return masterPosition;
}
}
}View on GitHub (pinned to 87be50e876)
Solutions
- Set canal.instance.slaveId explicitly to a unique positive integer so generateUniqueServerId() is never called.
- Ensure /etc/hosts contains an entry mapping the host's hostname to 127.0.0.1 (or its real IP).
- Fix DNS/resolution so `hostname -f` and InetAddress.getLocalHost() succeed.
Example fix
# /etc/hosts — ensure the container's hostname resolves 127.0.0.1 localhost my-canal-host # or set slaveId explicitly in instance.properties canal.instance.slaveId=12345
Defensive patterns
Strategy: validation
Validate before calling
// Avoid relying on InetAddress.getLocalHost()
if (slaveId <= 0) {
slaveId = readConfiguredSlaveId(); // from canal.instance.slaveId
if (slaveId <= 0) {
// sanity: ensure host resolution works before dump
try { InetAddress.getLocalHost(); }
catch (UnknownHostException uhe) {
throw new IllegalStateException("Cannot resolve local host and no canal.instance.slaveId set. Fix /etc/hosts or set slaveId.", uhe);
}
}
} Prevention
- Always set canal.instance.slaveId to a unique positive integer.
- Ensure /etc/hosts maps the container hostname to 127.0.0.1.
- Verify `hostname -f` resolves in the canal runtime environment.
When it happens
Trigger: canal.instance.slaveId is unset (<=0) and the container/host lacks a resolvable hostname in /etc/hosts or DNS. InetAddress.getLocalHost() then fails.
Common situations: Running canal in a minimal container without a localhost entry for its own hostname; a misconfigured /etc/hosts; DNS unreachable at startup.
Related errors
- Server certificate identity check failed. The certificate Co
- command : show variables like 'server_id' has an error!
- Unsupported ssl mode: {}
- Failed to retrieve the Common Name (CN) from the server cert
- load manager config failed.
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/7d2a8b070a9f9511.
Report an issue: GitHub.