{"record":{"id":"2ded0852aaa7e8a5","repo":"jwtk/jjwt","slug":"invalid-gson-instance-it-has-not-been-registered","errorCode":null,"errorMessage":"Invalid Gson instance - it has not been registered with the necessary  type adapter.  When using the GsonBuilder, ensure this type adapter is registered by calling gsonBuilder.registerTypeHierarchyAdapter(.class, .INSTANCE) before calling gsonBuilder.create()","messagePattern":"Invalid Gson instance - it has not been registered with the necessary  type adapter\\.  When using the GsonBuilder, ensure this type adapter is registered by calling gsonBuilder\\.registerTypeHierarchyAdapter\\(\\.class, \\.INSTANCE\\) before calling gsonBuilder\\.create\\(\\)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/gson/src/main/java/io/jsonwebtoken/gson/io/GsonSerializer.java","lineNumber":58,"sourceCode":"    protected final Gson gson;\n\n    public GsonSerializer() {\n        this(DEFAULT_GSON);\n    }\n\n    public GsonSerializer(Gson gson) {\n        Assert.notNull(gson, \"gson cannot be null.\");\n        this.gson = gson;\n\n        //ensure the necessary type adapter has been registered, and if not, throw an error:\n        String json = this.gson.toJson(TestConfidentialValue.INSTANCE);\n        if (json.contains(\"value\")) {\n            String msg = \"Invalid Gson instance - it has not been registered with the necessary \" +\n                    ConfidentialValue.class.getName() + \" type adapter.  When using the GsonBuilder, ensure this \" +\n                    \"type adapter is registered by calling gsonBuilder.registerTypeHierarchyAdapter(\" +\n                    ConfidentialValue.class.getName() + \".class, \" +\n                    GsonConfidentialValueSerializer.class.getName() + \".INSTANCE) before calling gsonBuilder.create()\";\n            throw new IllegalArgumentException(msg);\n        }\n    }\n\n    @Override\n    protected void doSerialize(T t, OutputStream out) {\n        Writer writer = new OutputStreamWriter(out, StandardCharsets.UTF_8);\n        try {\n            Object o = t;\n            if (o instanceof byte[]) {\n                o = Encoders.BASE64.encode((byte[]) o);\n            } else if (o instanceof char[]) {\n                o = new String((char[]) o);\n            }\n            writeValue(o, writer);\n        } finally {\n            Objects.nullSafeClose(writer);\n        }\n    }","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/extensions/gson/src/main/java/io/jsonwebtoken/gson/io/GsonSerializer.java#L40-L76","documentation":"GsonSerializer validates at construction that the provided Gson instance can serialize ConfidentialValue; if a test-round-trip JSON contains a \"value\" key the Gson instance lacks the required ConfidentialValue type adapter, and IllegalArgumentException is thrown. This ensures confidential (redacted) values are serialized through the proper adapter rather than leaked as plain JSON.","triggerScenarios":"Creating new GsonSerializer<>(gson) with a Gson built without gsonBuilder.registerTypeHierarchyAdapter(ConfidentialValue.class, GsonConfidentialValueSerializer.INSTANCE), then serializing claims containing ConfidentialValue.","commonSituations":"Setting up the Gson extension after upgrading JJWT to versions with ConfidentialCodec support; building a plain new Gson() or GsonBuilder().create() without registering the adapter.","solutions":["Register the adapter before create(): gsonBuilder.registerTypeHierarchyAdapter(ConfidentialValue.class, GsonConfidentialValueSerializer.INSTANCE)","Rebuild the Gson instance with the adapter and pass it to the serializer constructor","Follow the message's exact instruction including the .INSTANCE field of GsonConfidentialValueSerializer"],"exampleFix":"// before\nGson gson = new GsonBuilder().create();\nSerializer<?> s = new GsonSerializer<>(gson); // IllegalArgumentException on confidential values\n// after\nGson gson = new GsonBuilder()\n    .registerTypeHierarchyAdapter(ConfidentialValue.class, GsonConfidentialValueSerializer.INSTANCE)\n    .create();\nSerializer<?> s = new GsonSerializer<>(gson);","handlingStrategy":"validation","validationCode":"Gson gson = new GsonBuilder()\n    .registerTypeHierarchyAdapter(ConfidentialValue.class, GsonConfidentialValueSerializer.INSTANCE)\n    .create();\n// pass this gson instance to new GsonSerializer<>(gson)","typeGuard":null,"tryCatchPattern":"try {\n    serializer = new GsonSerializer<>(gson);\n} catch (IllegalArgumentException e) {\n    throw new IllegalStateException(\"Rebuild Gson with the ConfidentialValue type adapter registered\", e);\n}","preventionTips":["Centralize Gson construction in one factory that always registers the ConfidentialValue adapter","Never pass new Gson() or an unconfigured GsonBuilder().create() to GsonSerializer","Re-check serializer setup after JJWT upgrades that introduce new adapter requirements"],"tags":["java","jjwt","gson","serialization","configuration"],"backgroundTag":"missing-dependency","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}