apache/pulsar · error · MetadataFormatException

Failed to parse package metadata as JSON: ${message}

Error message

Failed to parse package metadata as JSON: ${message}

What it means

MetadataFormatException thrown by PackageMetadataUtil.readJson when Jackson fails to parse the payload as PackageMetadata JSON; the message includes the underlying IOException message. The bytes looked like JSON (leading '{') but were not valid or did not match the schema.

Source

Thrown at pulsar-package-management/core/src/main/java/org/apache/pulsar/packages/management/core/common/PackageMetadataUtil.java:98

        if (firstNonWhitespace >= 0 && bytes[firstNonWhitespace] == JSON_LEADING_BYTE) {
            return readJson(bytes);
        }
        if (bytes.length >= 2 && bytes[0] == JAVA_MAGIC_BYTE_0 && bytes[1] == JAVA_MAGIC_BYTE_1) {
            if (!allowLegacyJavaSerialization) {
                throw new MetadataFormatException(
                        "Package metadata is in legacy Java serialization format but reading it is disabled. "
                                + "Enable packagesManagementAllowLegacyJavaSerialization or re-upload the package.");
            }
            return readLegacy(bytes);
        }
        throw new MetadataFormatException("Unrecognized package metadata format");
    }

    private static PackageMetadata readJson(byte[] bytes) throws MetadataFormatException {
        try {
            return JSON_READER.readValue(bytes);
        } catch (IOException e) {
            throw new MetadataFormatException("Failed to parse package metadata as JSON: " + e.getMessage());
        }
    }

    private static PackageMetadata readLegacy(byte[] bytes) throws MetadataFormatException {
        try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
            ois.setObjectInputFilter(LEGACY_FILTER);
            Object o = ois.readObject();
            if (!(o instanceof PackageMetadata)) {
                throw new MetadataFormatException("Unexpected metadata type: "
                        + (o == null ? "null" : o.getClass().getName()));
            }
            if (LEGACY_READ_WARNED.compareAndSet(false, true)) {
                log.warn("Read a package metadata entry in the legacy Java serialization format. "
                        + "Re-upload packages or call updateMeta to migrate them to JSON, then disable "
                        + "packagesManagementAllowLegacyJavaSerialization.");
            }
            return (PackageMetadata) o;
        } catch (MetadataFormatException e) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Re-upload the package to rewrite valid JSON metadata.
  2. Validate the stored blob is well-formed JSON and matches PackageMetadata fields (description, contact, properties, etc.).
  3. Check the message suffix for the exact Jackson parse error (line/column or field mismatch).
  4. Compare the writer version that produced the blob; migrate blobs written by incompatible versions.

Example fix

// before
{"description": "pkg",  // truncated JSON
// after
{"description":"pkg","contact":"dev@example.com","properties":{}}
Defensive patterns

Strategy: try-catch

Validate before calling

// cheap pre-check that payload is plausible JSON before deep parse
if (bytes == null || bytes.length == 0 || bytes[0] != '{') {
    throw new IllegalArgumentException("payload is not JSON package metadata");
}

Try / catch

try {
    PackageMetadata m = PackageMetadataUtil.fromBytes(bytes, allowLegacy);
} catch (MetadataFormatException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Failed to parse package metadata as JSON")) {
        // log full blob (or hash), re-upload or restore from backup
    }
}

Prevention

When it happens

Trigger: fromBytes detecting a JSON-leading byte and calling readJson on malformed JSON, truncated JSON, or JSON with fields incompatible with PackageMetadata (wrong types, unknown structure).

Common situations: Hand-edited or partially-written metadata blobs, a writer from a different/incompatible version storing a different JSON shape, or corruption during storage/migration.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


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