apache/pulsar · error · MetadataFormatException
Package metadata is in legacy Java serialization format but
Error message
Package metadata is in legacy Java serialization format but reading it is disabled. Enable packagesManagementAllowLegacyJavaSerialization or re-upload the package.
What it means
MetadataFormatException thrown by PackageMetadataUtil.fromBytes when the payload starts with the Java serialization magic bytes but the packagesManagementAllowLegacyJavaSerialization flag is disabled. Older Pulsar versions stored metadata via Java serialization; reading such blobs now requires explicitly opting in.
Source
Thrown at pulsar-package-management/core/src/main/java/org/apache/pulsar/packages/management/core/common/PackageMetadataUtil.java:85
} catch (IOException e) {
throw new IllegalStateException("Failed to serialize package metadata as JSON", e);
}
}
return SerializationUtils.serialize(packageMetadata);
}
public static PackageMetadata fromBytes(byte[] bytes, boolean allowLegacyJavaSerialization)
throws MetadataFormatException {
if (bytes == null || bytes.length == 0) {
throw new MetadataFormatException("Empty package metadata");
}
int firstNonWhitespace = indexOfFirstNonWhitespace(bytes);
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))) {View on GitHub (pinned to 820761864e)
Solutions
- Re-upload the package with a current client so metadata is stored as JSON (recommended).
- Temporarily set packagesManagementAllowLegacyJavaSerialization=true on the broker to read the legacy blob.
- Confirm the blob's origin; if unexpected, treat it as possible tampering rather than enabling deserialization.
- Migrate all legacy packages after upgrade, then keep the flag disabled permanently.
Example fix
# before (broker.conf) packagesManagementAllowLegacyJavaSerialization=false # after (temporary migration only) packagesManagementAllowLegacyJavaSerialization=true
Defensive patterns
Strategy: fallback
Validate before calling
static boolean isLegacyJavaSerialized(byte[] b) {
return b != null && b.length >= 2 && b[0] == (byte) 0xAC && b[1] == (byte) 0xED;
}
// if isLegacyJavaSerialized(blob) && !allowLegacy -> plan re-upload before upgrade Try / catch
try {
PackageMetadata m = PackageMetadataUtil.fromBytes(bytes, allowLegacy);
} catch (MetadataFormatException e) {
if (e.getMessage() != null && e.getMessage().contains("legacy Java serialization")) {
// surface actionable guidance: re-upload or enable the flag temporarily
}
} Prevention
- Re-upload all packages after upgrading from legacy Pulsar versions.
- Keep packagesManagementAllowLegacyJavaSerialization=false by default for security.
- Inventory packages stored in legacy format before broker upgrades.
- Alert on MetadataFormatException mentioning legacy format to catch old blobs early.
When it happens
Trigger: Reading metadata of a package uploaded by an older Pulsar version (pre-JSON metadata) while the broker runs with packagesManagementAllowLegacyJavaSerialization=false (the safe default).
Common situations: Upgrading a cluster with packages uploaded by legacy versions, restoring old BookKeeper data into a new broker, or security-hardened deployments that keep legacy deserialization disabled.
Related errors
- Empty package metadata
- Unrecognized package metadata format
- Failed to parse package metadata as JSON: ${message}
- Invalid broker configuration. Authentication must be enabled
- Package Management Service is not enabled in the broker.
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/12ef40e40b9e34d5.
Report an issue: GitHub.