{"record":{"id":"9a1a70b38e56701d","repo":"alibaba/nacos","slug":"jackson-3-is-not-available-on-the-runtime-classpat","errorCode":null,"errorMessage":"Jackson 3 is not available on the runtime classpath.","messagePattern":"Jackson 3 is not available on the runtime classpath\\.","errorType":"exception","errorClass":"NacosLoadException","httpStatus":null,"severity":"critical","filePath":"common/src/main/java/com/alibaba/nacos/common/json/Jackson3JsonAdapter.java","lineNumber":155,"sourceCode":"            if (!subtypes.contains(subtype)) {\n                subtypes.add(subtype);\n            }\n            NacosJsonAdapter currentDelegate = delegate;\n            if (currentDelegate != null) {\n                currentDelegate.registerSubtype(subtype);\n            }\n        }\n    }\n    \n    private NacosJsonAdapter delegate() {\n        NacosJsonAdapter currentDelegate = delegate;\n        if (currentDelegate != null) {\n            return currentDelegate;\n        }\n        synchronized (this) {\n            if (delegate == null) {\n                if (!isAvailable()) {\n                    throw new NacosLoadException(\n                        \"Jackson 3 is not available on the runtime classpath.\");\n                }\n                delegate = createDelegate();\n            }\n            return delegate;\n        }\n    }\n    \n    private NacosJsonAdapter createDelegate() {\n        NacosJsonAdapter createdDelegate = new Jackson3JsonAdapterDelegate();\n        synchronized (subtypes) {\n            for (NacosJsonSubtype subtype : subtypes) {\n                createdDelegate.registerSubtype(subtype);\n            }\n        }\n        return createdDelegate;\n    }\n}","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/common/src/main/java/com/alibaba/nacos/common/json/Jackson3JsonAdapter.java#L137-L173","documentation":"Thrown by Jackson3JsonAdapter.delegate() when lazy initialization runs and isAvailable() returns false. isAvailable() does Class.forName for the Jackson 3 ObjectMapper and Exception classes; if either is missing from the runtime classpath, the adapter refuses to build a delegate and throws NacosLoadException. This is a hard dependency-resolution failure, not a serialization error.","triggerScenarios":"Selecting the JACKSON3 adapter (NacosJsonAdapterNames.JACKSON3) and invoking any JSON op when the Jackson 3 jars (tools.jackson.databind ObjectMapper, JacksonException) are not on the classpath; shading/uber-jar builds that excluded jackson 3; running on a runtime where the classes loaded but threw LinkageError/ServiceConfigurationError during Class.forName.","commonSituations":"App depends on the Nacos client jar which defaults to Jackson 2 but the SPI/config points at Jackson 3 without adding the jackson-3 dependency; a fat jar that deduplicated jackson classes; module path (jigsaw) setup not exporting the jackson 3 module; version conflict where jackson 3 API is present but the databind impl is absent.","solutions":["Add the Jackson 3 dependency to your build (e.g. tools.jackson:jackson-databind and its core) matching the version Nacos expects.","If you do not need Jackson 3, switch the configured adapter to Jackson 2 (the default) via the JSON SPI selection instead of forcing JACKSON3.","Run with -verbose:class to confirm the Jackson 3 ObjectMapper class is resolvable at runtime.","In a fat/shaded jar, verify the shade plugin did not exclude jackson 3 packages and that services entries are preserved."],"exampleFix":"// before — JACKSON3 selected but jars missing\n// Nacos loads Jackson3JsonAdapter, isAvailable()==false -> NacosLoadException\n\n// after — Maven adds jackson 3\n// <dependency>\n//   <groupId>tools.jackson</groupId>\n//   <artifactId>jackson-databind</artifactId>\n//   <version>3.x</version>\n// </dependency>\n// OR select the default Jackson 2 adapter instead","handlingStrategy":"validation","validationCode":"if (!adapter.isAvailable()) {\n    // fall back to the default Jackson 2 adapter, or fail with a clear message\n    throw new IllegalStateException(\n        \"Jackson 3 not on classpath; add tools.jackson:jackson-databind or switch adapters\");\n}","typeGuard":"boolean jackson3Present(ClassLoader cl) {\n    try { Class.forName(\"tools.jackson.databind.ObjectMapper\", false, cl); return true; }\n    catch (Throwable t) { return false; }\n}","tryCatchPattern":"try {\n    String json = adapter.toJson(obj);\n} catch (NacosLoadException e) {\n    // Jackson 3 missing — either add the dependency or select Jackson 2\n    log.error(\"JSON backend unavailable: {}\", e.getMessage());\n    throw e;\n}","preventionTips":["Only select the JACKSON3 adapter if you have added the Jackson 3 dependencies.","Run -verbose:class or a Class.forName probe at startup to confirm availability.","In shaded jars, verify the shade plugin keeps jackson 3 packages and services."],"tags":["classpath","jackson3","dependency","init"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}