apache/skywalking · error · UnexpectedException
Can't split service id into 2 parts, {}
Error message
Can't split service id into 2 parts, {} What it means
UnexpectedException thrown by IDManager.ServiceID.analysisId(String) when a service ID string cannot be split into exactly 2 parts by Const.SERVICE_ID_PARSER_SPLIT. Service IDs are built by buildId(name, isNormal) as encode(name) + '.' + booleanValue(0/1); analysisId is the inverse and treats any other shape as data corruption. The offending id is included in the message.
Source
Thrown at oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/IDManager.java:59
/**
* @param name service name
* @param isNormal `true` represents this service is detected by an agent. `false` represents this service is
* conjectured by telemetry data collected from agents on/in the `normal` service.
*/
public static String buildId(String name, boolean isNormal) {
if (StringUtil.isBlank(name)) {
name = Const.BLANK_ENTITY_NAME;
}
return encode(name) + Const.SERVICE_ID_CONNECTOR + BooleanUtils.booleanToValue(isNormal);
}
/**
* @return service ID object decoded from {@link #buildId(String, boolean)} result
*/
public static ServiceIDDefinition analysisId(String id) {
final String[] strings = id.split(Const.SERVICE_ID_PARSER_SPLIT);
if (strings.length != 2) {
throw new UnexpectedException("Can't split service id into 2 parts, " + id);
}
return new ServiceID.ServiceIDDefinition(
decode(strings[0]),
BooleanUtils.valueToBoolean(Integer.parseInt(strings[1]))
);
}
/**
* @return encoded service relation id
*/
public static String buildRelationId(ServiceRelationDefine define) {
return define.sourceId + Const.RELATION_ID_CONNECTOR + define.destId;
}
/**
* @return encoded service hierarchy relation id
*/
public static String buildServiceHierarchyRelationId(ServiceHierarchyRelationDefine define) {View on GitHub (pinned to 102af09b4a)
Solutions
- Always build ids with IDManager.ServiceID.buildId(name, isNormal) and only pass those to analysisId
- If hand-constructing, match the exact format: URL-encoded name + Const.SERVICE_ID_CONNECTOR + '0'|'1'
- Log the failing id (it is in the message) and trace which writer produced it — usually a non-standard producer
- On version-skew migrations, reindex/rewrite stored ids or read them with the old format
Example fix
// before ServiceIDDefinition def = IDManager.ServiceID.analysisId(serviceName); // raw name -> throws // after String id = IDManager.ServiceID.buildId(serviceName, true); ServiceIDDefinition def = IDManager.ServiceID.analysisId(id);
Defensive patterns
Strategy: type-guard
Validate before calling
String PATTERN = "^[^.]+\\.[01]$"; // encoded-name '.' 0|1
if (id == null || !id.matches(PATTERN)) {
throw new IllegalArgumentException("Not a service id produced by IDManager.ServiceID.buildId: " + id);
} Type guard
boolean isServiceId(String id) {
return id != null && id.matches("^[^.]+\\.[01]$");
} Try / catch
try {
ServiceIDDefinition def = IDManager.ServiceID.analysisId(id);
} catch (UnexpectedException e) {
LOGGER.warn("Skipping malformed service id: {}", id, e);
} Prevention
- Never hand-assemble ids; always round-trip through buildId/analysisId from the same IDManager version
- Keep the id format constant across services — never store ids from a newer OAP into data read by an older one
- In tests, generate ids only via buildId
When it happens
Trigger: Calling ServiceID.analysisId on a string that is not a buildId product: a raw service name without the connector, an id built with a different connector constant, an id with extra '.' segments because the encoded name leaks an unencoded '.', or null/empty passed in.
Common situations: Custom storage/receiver code re-implementing id assembly instead of calling buildId; version skew where a producer encodes differently than the consumer decodes; unit tests feeding hand-crafted ids; data written by an old OAP being read by new code after encoding changes.
Related errors
- Illegal Service Relation entity id
- Can't split instance id into 2 parts, {}
- Illegal Service Instance Relation entity id
- Can't split endpoint id into 2 parts, {}
- Illegal endpoint Relation entity id, {}
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/2c1b3c33da11e86c.
Report an issue: GitHub.