pinpoint-apm/pinpoint · error · IllegalArgumentException

invalid metadata rowkey length

Error message

invalid metadata rowkey length: ${rowKey.length}

What it means

MetadataDecoder.readServiceUid parses the serviceUid prefix of a metadata row key, which must be either 0 bytes (default serviceUid) or exactly INT_BYTE_LENGTH (4 bytes). Any other remaining rowKey length means the key layout is invalid, so the decoder throws this IllegalArgumentException.

Solutions

  1. Check the row key length and content before decoding; skip or quarantine malformed keys
  2. Regenerate the row key using the current MetadataRowKey/encoder utilities instead of hand-built byte arrays
  3. Verify data and server versions match the expected metadata rowkey schema; migrate old rows if needed

Example fix

// before
ServiceUid uid = decoder.readServiceUid(rowKey, offset); // throws for odd lengths
// after
int rem = rowKey.length - offset;
if (rem != 0 && rem != BytesUtils.INT_BYTE_LENGTH) {
    logger.warn("Skipping malformed metadata rowkey length " + rowKey.length);
    return; // or use ServiceUid.DEFAULT
}
ServiceUid uid = decoder.readServiceUid(rowKey, offset);
Defensive patterns

Strategy: validation

Validate before calling

int remaining = rowKey.length - offset;
if (remaining != 0 && remaining != BytesUtils.INT_BYTE_LENGTH) {
    logger.warn("Invalid metadata rowkey length " + rowKey.length);
    return; // skip malformed row
}

Type guard

boolean hasValidServiceUidRegion(byte[] rowKey, int offset) {
    int rem = rowKey.length - offset;
    return rem == 0 || rem == BytesUtils.INT_BYTE_LENGTH;
}

Try / catch

try {
    ServiceUid uid = MetadataDecoder.readServiceUid(rowKey, offset);
} catch (IllegalArgumentException e) {
    logger.warn("Malformed metadata rowkey: " + Arrays.toString(rowKey), e);
    // skip or migrate row
}

Prevention

When it happens

Trigger: Decoding a metadata row key whose length is neither 0 nor 4 bytes in the serviceUid region, e.g. a truncated/corrupted HBase row key, a key produced by a different schema version, or an incorrectly constructed key written by custom tooling.

Common situations: Reading rows written by an older/newer Pinpoint version whose metadata rowkey layout differs; manual row scans/repairs copying wrong-length keys; applicationName/agentId changes shifting key offsets in hand-built keys.

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/a4696e555c688317. Report an issue: GitHub.

Appendix: source

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

    private long readAgentStartTime(byte[] rowKey, int offset) {
        return LongInverter.restore(ByteArrayUtils.bytesToLong(rowKey, offset));
    }

    private int readId(byte[] rowKey, int offset) {
        return ByteArrayUtils.bytesToInt(rowKey, offset);
    }

    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)