{"record":{"id":"e47d2b67aded3c95","repo":"apache/pulsar","slug":"rejected-legacy-package-metadata","errorCode":null,"errorMessage":"Rejected legacy package metadata: ","messagePattern":"Rejected legacy package metadata: ","errorType":"exception","errorClass":"MetadataFormatException","httpStatus":null,"severity":"error","filePath":"pulsar-package-management/core/src/main/java/org/apache/pulsar/packages/management/core/common/PackageMetadataUtil.java","lineNumber":119,"sourceCode":"\n    private static PackageMetadata readLegacy(byte[] bytes) throws MetadataFormatException {\n        try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes))) {\n            ois.setObjectInputFilter(LEGACY_FILTER);\n            Object o = ois.readObject();\n            if (!(o instanceof PackageMetadata)) {\n                throw new MetadataFormatException(\"Unexpected metadata type: \"\n                        + (o == null ? \"null\" : o.getClass().getName()));\n            }\n            if (LEGACY_READ_WARNED.compareAndSet(false, true)) {\n                log.warn(\"Read a package metadata entry in the legacy Java serialization format. \"\n                        + \"Re-upload packages or call updateMeta to migrate them to JSON, then disable \"\n                        + \"packagesManagementAllowLegacyJavaSerialization.\");\n            }\n            return (PackageMetadata) o;\n        } catch (MetadataFormatException e) {\n            throw e;\n        } catch (Exception e) {\n            throw new MetadataFormatException(\"Rejected legacy package metadata: \" + e.getMessage());\n        }\n    }\n\n    private static int indexOfFirstNonWhitespace(byte[] bytes) {\n        for (int i = 0; i < bytes.length; i++) {\n            byte b = bytes[i];\n            if (b != ' ' && b != '\\t' && b != '\\n' && b != '\\r') {\n                return i;\n            }\n        }\n        return -1;\n    }\n\n    // Source-compatible overloads for callers (including external integrations) that haven't\n    // been updated to the explicit-flag form. Defaults track the production defaults.\n    @Deprecated\n    public static byte[] toBytes(PackageMetadata packageMetadata) {\n        return toBytes(packageMetadata, true);","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-package-management/core/src/main/java/org/apache/pulsar/packages/management/core/common/PackageMetadataUtil.java#L101-L137","documentation":"This is the catch-all wrapper in readLegacy: any exception thrown while reading legacy Java-serialized metadata (InvalidClassException, ClassNotFoundException, StreamCorruptedException, EOFException, etc.) is rethrown as MetadataFormatException with the original message appended. It signals the stored bytes could not be safely deserialized as legacy package metadata.","triggerScenarios":"fromBytes() is given bytes in the legacy format that fail deserialization: stream corrupted, class not found on classpath, class version mismatch, or the ObjectInputFilter rejected a field/class (e.g. a nested non-whitelisted object inside PackageMetadata).","commonSituations":"Pulsar upgrade changed the PackageMetadata class shape (serialVersionUID mismatch); metadata blob truncated or corrupted on disk/storage backend; security filter (LEGACY_FILTER) rejects classes referenced in the serialized graph.","solutions":["Re-upload the package or call updateMeta to migrate the entry to JSON format, then disable packagesManagementAllowLegacyJavaSerialization.","Inspect the wrapped message in the MetadataFormatException to identify the underlying cause (class-not-found vs corrupted stream vs filter rejection).","If the class shape changed across versions, migrate metadata using the same Pulsar version that wrote it.","Delete and recreate the affected package metadata entry."],"exampleFix":"// before: relying on legacy serialization\nconf.setPackagesManagementAllowLegacyJavaSerialization(true);\n// after: migrate and disable legacy support\nmetadataService.updateMetadata(packageName, PackageMetadataUtil.toBytes(newMetadata));\nconf.setPackagesManagementAllowLegacyJavaSerialization(false);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    PackageMetadata m = PackageMetadataUtil.fromBytes(bytes);\n} catch (MetadataFormatException e) {\n    Throwable cause = e.getCause();\n    log.warn(\"Legacy metadata rejected: {} (cause: {})\", e.getMessage(), cause, e);\n    // treat as corrupt entry: re-upload or delete\n}","preventionTips":["Migrate legacy entries with updateMeta before upgrading Pulsar versions.","Avoid mixing storage dirs between Pulsar versions without migration.","Keep the serialized class shape stable or always rewrite metadata in JSON.","Monitor for MetadataFormatException from read paths."],"tags":["java","deserialization","serialization","package-management"],"backgroundTag":"java-deserialization-invalid-type","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}