apache/pulsar · error · MetadataStoreException

Invalid MetaValue data, size=${size}

Error message

Invalid MetaValue data, size=${size}

What it means

RocksdbMetadataStore serializes each value as a MetaValue: a 4-byte big-endian headerSize int followed by the header/serialized metadata. MetaValue.parse() rejects byte arrays shorter than 4 bytes because they cannot even contain the header length field, throwing MetadataStoreException("Invalid MetaValue data, size=N").

Source

Thrown at pulsar-metadata/src/main/java/org/apache/pulsar/metadata/impl/RocksdbMetadataStore.java:157

            byte[] result = new byte[HEADER_SIZE + data.length];
            ByteBuffer buffer = ByteBuffer.wrap(result);
            buffer.putInt(HEADER_SIZE);
            buffer.putInt(FORMAT_VERSION_V1);
            buffer.putLong(version);
            buffer.putLong(owner);
            buffer.putLong(createdTimestamp);
            buffer.putLong(modifiedTimestamp);
            buffer.put((byte) (ephemeral ? 1 : 0));
            buffer.put(data);
            return result;
        }

        public static MetaValue parse(byte[] dataBytes) throws MetadataStoreException {
            if (dataBytes == null) {
                return null;
            }
            if (dataBytes.length < 4) {
                throw new MetadataStoreException("Invalid MetaValue data, size=" + dataBytes.length);
            }
            ByteBuffer buffer = ByteBuffer.wrap(dataBytes);
            MetaValue metaValue = new MetaValue();
            int headerSize = buffer.getInt();
            if (dataBytes.length < headerSize) {
                throw new MetadataStoreException(
                        String.format("Invalid MetaValue data, no enough header data. expect %d, actual %d",
                                headerSize, dataBytes.length));
            }
            int formatVersion = buffer.getInt();
            if (formatVersion >= FORMAT_VERSION_V1) {
                metaValue.version = buffer.getLong();
                metaValue.owner = buffer.getLong();
                metaValue.createdTimestamp = buffer.getLong();
                metaValue.modifiedTimestamp = buffer.getLong();
                metaValue.ephemeral = buffer.get() > 0;
            } else {
                throw new MetadataStoreException("Invalid MetaValue format version=" + formatVersion);

View on GitHub (pinned to 820761864e)

Solutions

  1. Restore the RocksDB metadata directory from a backup taken while the store was stopped
  2. Re-serialize values through MetaValue's write path instead of writing raw bytes into the store
  3. If the directory is corrupted, rebuild the metadata store and re-import metadata (or re-run migration tooling)
  4. Do not copy/edit RocksDB files while the metadata store is running

Example fix

// before
rocksDBStore.put(path, "{\"value\":1}".getBytes()); // raw bytes, not MetaValue
// after
rocksDBStore.put(path, new MetaValue(/* header */).serialize(/* value */)); // proper MetaValue encoding
Defensive patterns

Strategy: try-catch

Validate before calling

// Java: sanity-check record size before parsing
current = rocksDB.get(readOptions, key);
if (current != null && current.length < 4) {
    throw new IOException("Corrupted record (size " + current.length + ") for key " + key);
}

Type guard

boolean looksLikeMetaValue(byte[] data) {
    return data != null && data.length >= 4
        && data.length >= ByteBuffer.wrap(data).getInt(); // length >= declared headerSize
}

Try / catch

try {
    MetaValue mv = MetaValue.parse(bytes);
} catch (MetadataStoreException e) {
    // record corrupted/foreign: restore from backup or rebuild store
}

Prevention

When it happens

Trigger: Reading a RocksDB record whose stored bytes are shorter than 4 bytes — corrupted database files, manual writes of raw values bypassing MetaValue encoding, truncation, or a store written by an incompatible format version.

Common situations: A RocksDB metadata directory corrupted by an earlier crash or copied while the store was live; scripts writing plain JSON/bytes directly into RocksDB; mixing store versions that changed the on-disk format.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/44b8e80fc010efeb. Report an issue: GitHub.