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

  1. Create ids only with IDManager.EndpointID.buildId(serviceId, endpointName) (it URL-encodes the name) and decode only its output
  2. Audit custom analyzers for manual string concatenation of serviceId + '.' + endpointName and replace with buildId
  3. Use the id embedded in the exception message to trace the offending producer
  4. 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

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


AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14). Data as JSON: /api/errors/32685876a57fb8e5. Report an issue: GitHub.