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

  1. Always build ids with IDManager.ServiceID.buildId(name, isNormal) and only pass those to analysisId
  2. If hand-constructing, match the exact format: URL-encoded name + Const.SERVICE_ID_CONNECTOR + '0'|'1'
  3. Log the failing id (it is in the message) and trace which writer produced it — usually a non-standard producer
  4. 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

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


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