{"record":{"id":"98e3f5893612ea28","repo":"quarkusio/quarkus","slug":"failed-to-parse-quarkus-extension-catalog-jsonpa","errorCode":null,"errorMessage":"Failed to parse Quarkus extension catalog ${jsonPath}","messagePattern":"Failed to parse Quarkus extension catalog (.+?)","errorType":"exception","errorClass":"RegistryResolutionException","httpStatus":null,"severity":"error","filePath":"independent-projects/tools/registry-client/src/main/java/io/quarkus/registry/client/maven/MavenPlatformExtensionsResolver.java","lineNumber":81,"sourceCode":"            if (repo != null) {\n                buf.append(\" from Maven repository \").append(repo.getId()).append(\" (\").append(repo.getUrl()).append(\")\");\n                final List<RemoteRepository> mirrored = repo.getMirroredRepositories();\n                if (!mirrored.isEmpty()) {\n                    buf.append(\" which is a mirror of \");\n                    buf.append(mirrored.get(0).getId()).append(\" (\").append(mirrored.get(0).getUrl()).append(\")\");\n                    for (int i = 1; i < mirrored.size(); ++i) {\n                        buf.append(\", \").append(mirrored.get(i).getId()).append(\" (\").append(mirrored.get(i).getUrl())\n                                .append(\")\");\n                    }\n                    buf.append(\". The mirror may be out of sync.\");\n                }\n            }\n            throw new RegistryResolutionException(buf.toString(), e);\n        }\n        try {\n            return ExtensionCatalog.mutableFromFile(jsonPath);\n        } catch (IOException e) {\n            throw new RegistryResolutionException(\"Failed to parse Quarkus extension catalog \" + jsonPath, e);\n        }\n    }\n\n    private String resolveLatestBomVersion(ArtifactCoords bom, String versionRange)\n            throws RegistryResolutionException {\n        final Artifact bomArtifact = new DefaultArtifact(bom.getGroupId(),\n                PlatformArtifacts.ensureBomArtifactId(bom.getArtifactId()),\n                \"\", \"pom\", bom.getVersion());\n        log.debug(\"Resolving the latest version of %s:%s:%s:%s in the range %s\", bom.getGroupId(), bom.getArtifactId(),\n                bom.getClassifier(), bom.getType(), versionRange);\n        try {\n            return artifactResolver.getLatestVersionFromRange(bomArtifact, versionRange);\n        } catch (Exception e) {\n            throw new RegistryResolutionException(\"Failed to resolve the latest version of \" + bomArtifact.getGroupId()\n                    + \":\" + bom.getArtifactId() + \":\" + bom.getClassifier() + \":\" + bom.getType() + \":\" + versionRange, e);\n        }\n    }\n","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/tools/registry-client/src/main/java/io/quarkus/registry/client/maven/MavenPlatformExtensionsResolver.java#L63-L99","documentation":"This error is thrown by MavenPlatformExtensionsResolver.resolvePlatformExtensions when the downloaded Quarkus extension catalog JSON file could not be read or parsed. The resolver fetched the catalog artifact for a platform BOM, then ExtensionCatalog.mutableFromFile(jsonPath) failed with an IOException while opening or deserializing the JSON. The original IOException is preserved as the cause.","triggerScenarios":"Calling resolvePlatformExtensions with a platform BOM whose extension-catalog JSON artifact exists on disk but is corrupted, truncated, partially downloaded, empty, or not valid Quarkus extension-catalog JSON; also when jsonPath points to a file that cannot be opened (permissions, deleted mid-run).","commonSituations":"A corrupted local Maven repository cache (~/.m2/repository) after an interrupted download; a mirror or corporate proxy serving an HTML error page saved as the catalog JSON; an extension catalog produced by an incompatible Quarkus registry/JSON schema version; read-permission problems in a shared CI cache.","solutions":["Delete the stale catalog file from the local Maven repository (e.g. rm -rf ~/.m2/repository/io/quarkus/platform/<g>/<a>/<v>) and retry, forcing re-download.","Verify the file at the path printed in the message is valid JSON (jq . <path>) and not an HTML error page; fix the proxy/mirror if it is.","Run with a clean local repo (mvn -U or -Dmaven.repo.local=<fresh-dir>) to rule out cache corruption.","Confirm the Quarkus platform/registry versions match between project config and the registry client; mismatched JSON schema versions can fail parsing.","Check file permissions on the local repository directory."],"exampleFix":"// before: relying on a possibly corrupted shared cache\nmvn quarkus:update -DplatformArtifact=io.quarkus.platform:quarkus-bom:2.16.0\n// after: force fresh resolution with a clean local repo\nmvn -Dmaven.repo.local=/tmp/clean-m2 quarkus:update -DplatformArtifact=io.quarkus.platform:quarkus-bom:2.16.0","handlingStrategy":"try-catch","validationCode":"Path jsonPath = Path.of(\"...catalog.json\");\n// pre-check: file exists, readable, non-empty, and looks like JSON\nif (!Files.isReadable(jsonPath) || Files.size(jsonPath) == 0) {\n    throw new IllegalStateException(\"Catalog file missing/empty: \" + jsonPath);\n}\ntry (var parser = Json.createParser(Files.newBufferedReader(jsonPath))) {\n    while (parser.hasNext()) parser.next(); // throws if malformed\n}","typeGuard":"static boolean isReadableJsonFile(Path p) {\n    try {\n        return Files.isRegularFile(p) && Files.isReadable(p)\n            && Files.size(p) > 0\n            && p.getFileName().toString().endsWith(\".json\");\n    } catch (IOException e) { return false; }\n}","tryCatchPattern":"try {\n    catalog = resolver.resolvePlatformExtensions(bom, quarkusVersion);\n} catch (RegistryResolutionException e) {\n    if (e.getMessage().startsWith(\"Failed to parse Quarkus extension catalog\")) {\n        // corrupt catalog: purge cached file and retry once\n        Files.deleteIfExists(Path.of(e.getMessage().replace(\"Failed to parse Quarkus extension catalog \", \"\")));\n        catalog = resolver.resolvePlatformExtensions(bom, quarkusVersion);\n    } else throw e;\n}","preventionTips":["Periodically clean or validate the local Maven repository cache (~/.m2/repository).","Pin explicit platform BOM versions rather than relying on dynamically served catalogs.","Use reliable mirrors/proxies that forward artifact bytes verbatim, not error pages.","Check cause chain (e.getCause() instanceof IOException) to distinguish corruption from network issues.","Run with a writable, user-owned local repository directory."],"tags":["maven","json-parsing","registry","quarkus-platform","cache-corruption"],"backgroundTag":"json-parse-failed","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}