pinpoint-apm/pinpoint · error · IllegalArgumentException

invalid metadata serviceUid: ${serviceUid}

Error message

invalid metadata serviceUid: ${serviceUid}

What it means

MetadataDecoder.validateServiceUid throws IllegalArgumentException when a decoded ServiceUid equals the ERROR or UNKNOWN sentinel values. It guards the binary metadata decoding path (readServiceUid) against corrupt or unwritten UID bytes that decode to reserved sentinel values. A valid metadata record must always carry a concrete service UID.

Source

Thrown at commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/metadata/MetadataDecoder.java:77

    }

    private ServiceUid readServiceUid(byte[] rowKey, int offset) {
        final int remaining = rowKey.length - offset;
        if (remaining == 0) {
            return ServiceUid.DEFAULT;
        } else if (remaining == BytesUtils.INT_BYTE_LENGTH) {
            ServiceUid serviceUid = ServiceUid.of(ByteArrayUtils.bytesToInt(rowKey, offset));
            validateServiceUid(serviceUid);
            return serviceUid;
        } else {
            throw new IllegalArgumentException("invalid metadata rowkey length: " + rowKey.length);
        }
    }

    private static void validateServiceUid(ServiceUid serviceUid) {
        if (ServiceUid.ERROR.equals(serviceUid)
                || ServiceUid.UNKNOWN.equals(serviceUid)) {
            throw new IllegalArgumentException("invalid metadata serviceUid: " + serviceUid);
        }
    }
}

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Inspect the raw source bytes/cell that produced the ServiceUid and confirm the serviceUid field was actually written by the producer
  2. Regenerate or rewrite the metadata record with a valid ServiceUid (not ERROR/UNKNOWN sentinels)
  3. Check writer/reader version compatibility — old rows written before serviceUid was introduced may need migration
  4. Wrap decode calls in try-catch for IllegalArgumentException and skip/log the malformed record instead of failing the whole scan

Example fix

// before
ServiceUid serviceUid = decoder.readServiceUid(buffer); // throws on sentinel
// after
if (ServiceUid.ERROR.equals(serviceUid) || ServiceUid.UNKNOWN.equals(serviceUid)) {
    logger.warn("skipping metadata with sentinel serviceUid");
    return null;
}
Defensive patterns

Strategy: validation

Validate before calling

if (ServiceUid.ERROR.equals(uid) || ServiceUid.UNKNOWN.equals(uid)) { skipOrReject(uid); }

Type guard

boolean isValidServiceUid(ServiceUid uid) { return uid != null && !ServiceUid.ERROR.equals(uid) && !ServiceUid.UNKNOWN.equals(uid); }

Try / catch

try { decoder.decode(bytes); } catch (IllegalArgumentException e) { log.warn("malformed metadata: {}", e.getMessage()); }

Prevention

When it happens

Trigger: Decoding metadata bytes whose serviceUid long value decodes to ServiceUid.ERROR or ServiceUid.UNKNOWN sentinels, e.g. reading a corrupted hbase cell, a record written by an older writer with unset UID, or deserializing an empty/default buffer.

Common situations: HBase cells written before serviceUid was populated; schema/version mismatch between writer and reader; corrupted serialized payload; tests feeding dummy zero-value buffers into MetadataDecoder.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/313ec5e565756973. Report an issue: GitHub.