{"record":{"id":"6ea09f8e6e2962fa","repo":"pinpoint-apm/pinpoint","slug":"invalid-bootstrap-class-loader-cl","errorCode":null,"errorMessage":"Invalid bootstrap class loader. cl={}","messagePattern":"Invalid bootstrap class loader\\. cl=(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/classloading/BootstrapClassLoaderHandler.java","lineNumber":96,"sourceCode":"        }\n    }\n\n    @Override\n    public InputStream getResourceAsStream(ClassLoader targetClassLoader, String internalName) {\n        try {\n            if (targetClassLoader == null) {\n                ClassLoader classLoader = ClassLoader.getSystemClassLoader();\n                if (classLoader == null) {\n                    return null;\n                }\n                appendToBootstrapClassLoaderSearch();\n                return classLoader.getResourceAsStream(internalName);\n            }\n        } catch (Exception e) {\n            logger.warn(\"Failed to load plugin resource as stream {} with classLoader\", internalName, e);\n            return null;\n        }\n        logger.warn(\"Invalid bootstrap class loader. cl={}\", targetClassLoader);\n        return null;\n    }\n}","sourceCodeStart":78,"sourceCodeEnd":99,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/classloading/BootstrapClassLoaderHandler.java#L78-L99","documentation":"This warn is the fallback path of BootstrapClassLoaderHandler.getResourceAsStream: the provided targetClassLoader is not the bootstrap classloader, so the handler refuses to look up the resource and returns null. It signals an API misuse — a bootstrap-classloader-only handler was given a non-bootstrap loader.","triggerScenarios":"getResourceAsStream invoked with any ClassLoader other than the bootstrap loader (PluginClassInjector only routes here when the target loader is the bootstrap loader, so a routing/mismatch or custom call with the wrong loader triggers it).","commonSituations":"Custom instrumentation code calling the bootstrap handler directly with an application classloader; changes in loader routing logic; classloader identity assumptions broken by custom containers.","solutions":["Verify targetClassLoader is actually the bootstrap loader before calling this handler.","Route non-bootstrap loaders to PlainClassLoaderHandler (or URLClassLoaderHandler) in PluginClassInjector.","Log/handle the null return instead of assuming a valid stream.","Check for containers that wrap the bootstrap loader in a delegating wrapper and compare against Object.class.getClassLoader() semantics."],"exampleFix":"// before\nhandler.getResourceAsStream(targetClassLoader, internalName);\n// after\nif (targetClassLoader == Object.class.getClassLoader()) {\n    return bootstrapHandler.getResourceAsStream(targetClassLoader, internalName);\n}\nreturn plainHandler.getResourceAsStream(targetClassLoader, internalName);","handlingStrategy":"type-guard","validationCode":"boolean isBootstrap = (targetClassLoader == Object.class.getClassLoader());","typeGuard":"static boolean isBootstrapClassLoader(ClassLoader cl) {\n    return cl == Object.class.getClassLoader();\n}","tryCatchPattern":null,"preventionTips":["Always check loader identity before calling bootstrap-only handlers","Route non-bootstrap loaders to PlainClassLoaderHandler","Beware container wrappers around the bootstrap loader","Treat a null return as a routing bug signal"],"tags":["classloader","plugin","argument-mismatch"],"backgroundTag":"invalid-argument-value","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}