apache/skywalking · error · UnexpectedException
Can't split endpoint id into 2 parts, {}
Error message
Can't split endpoint id into 2 parts, {} What it means
UnexpectedException thrown by IDManager.EndpointID.analysisId(String) when an endpoint id does not split into exactly 2 parts. Endpoint ids are built by buildId(serviceId, endpointName) as serviceId + '.' + encode(endpointName); analysisId is the strict inverse and includes the failing id in the message to aid diagnosis.
Source
Thrown at oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/IDManager.java:241
* @param serviceId built by {@link ServiceID#buildId(String, boolean)}
* @return endpoint id
*/
public static String buildId(String serviceId, String endpointName) {
if (StringUtil.isBlank(endpointName)) {
endpointName = Const.BLANK_ENTITY_NAME;
}
return serviceId
+ Const.ID_CONNECTOR
+ encode(endpointName);
}
/**
* @return Endpoint id object decoded from {@link #buildId(String, String)} result.
*/
public static EndpointIDDefinition analysisId(String id) {
final String[] strings = id.split(Const.ID_PARSER_SPLIT);
if (strings.length != 2) {
throw new UnexpectedException("Can't split endpoint id into 2 parts, " + id);
}
return new EndpointIDDefinition(
strings[0],
decode(strings[1])
);
}
/**
* @return the endpoint relationship string id.
*/
public static String buildRelationId(EndpointRelationDefine define) {
return define.sourceServiceId
+ Const.RELATION_ID_CONNECTOR
+ encode(define.source)
+ Const.RELATION_ID_CONNECTOR
+ define.destServiceId
+ Const.RELATION_ID_CONNECTOR
+ encode(define.dest);View on GitHub (pinned to 102af09b4a)
Solutions
- Create ids only with IDManager.EndpointID.buildId(serviceId, endpointName) (it URL-encodes the name) and decode only its output
- Audit custom analyzers for manual string concatenation of serviceId + '.' + endpointName and replace with buildId
- Use the id embedded in the exception message to trace the offending producer
- For stored bad ids, reindex or drop the affected endpoint rows
Example fix
// before String id = serviceId + "." + endpointName; // '/api/v1.users' breaks the split EndpointIDDefinition def = IDManager.EndpointID.analysisId(id); // after String id = IDManager.EndpointID.buildId(serviceId, endpointName); EndpointIDDefinition def = IDManager.EndpointID.analysisId(id);
Defensive patterns
Strategy: type-guard
Validate before calling
if (id == null || id.split("\\.").length != 2) {
throw new IllegalArgumentException("Not an endpoint id produced by IDManager.EndpointID.buildId: " + id);
} Type guard
boolean isEndpointId(String id) {
return id != null && id.split("\\.").length == 2;
} Try / catch
try {
EndpointIDDefinition def = IDManager.EndpointID.analysisId(id);
} catch (UnexpectedException e) {
LOGGER.warn("Skipping malformed endpoint id: {}", id, e);
} Prevention
- Endpoint names are URL-like and contain '.'; always rely on buildId's encoding instead of manual concat
- In LAL/MAL or custom fetchers, resolve endpoint ids through IDManager only
- When upgrading OAP across encoding changes, reindex stored endpoint rows before enabling queries
When it happens
Trigger: Passing a raw endpoint name (e.g. '/api/users'), an id whose endpoint name was not URL-encoded so its own separators break the split, an id with extra segments, or null into analysisId.
Common situations: Endpoint names are URLs and naturally contain '.' — any producer skipping encode() produces unparseable ids; custom log/LAL or MAL rules constructing endpoint ids manually; tests with hand-made ids; data from versions with different encoding.
Related errors
- Can't split service id into 2 parts, {}
- Illegal Service Relation entity id
- Can't split instance id into 2 parts, {}
- Illegal Service Instance Relation entity id
- Illegal endpoint Relation entity id, {}
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/32685876a57fb8e5.
Report an issue: GitHub.