{"record":{"id":"ea95ffc4eec44701","repo":"FasterXML/jackson-databind","slug":"cannot-set-maxtypefactorycachesize-to-a-negative-v","errorCode":null,"errorMessage":"Cannot set maxTypeFactoryCacheSize to a negative value","messagePattern":"Cannot set maxTypeFactoryCacheSize to a negative value","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/tools/jackson/databind/cfg/DefaultCacheProvider.java","lineNumber":202,"sourceCode":"                throw new IllegalArgumentException(\"Cannot set maxSerializerCacheSize to a negative value\");\n            }\n            _maxSerializerCacheSize = maxSerializerCacheSize;\n            return this;\n        }\n\n        /**\n         * Define the maximum size of the {@link LookupCache} instance constructed by {@link #forTypeFactory()}\n         * and {@link #_buildCache(int)}\n         * <p>\n         * Note that specifying a maximum size of zero prevents values from being retained in the cache.\n         *\n         * @param maxTypeFactoryCacheSize Size for the {@link LookupCache} to use within {@link tools.jackson.databind.type.TypeFactory}\n         * @return this builder\n         * @throws IllegalArgumentException if {@code maxTypeFactoryCacheSize} is negative\n         */\n        public Builder maxTypeFactoryCacheSize(int maxTypeFactoryCacheSize) {\n            if (maxTypeFactoryCacheSize < 0) {\n                throw new IllegalArgumentException(\"Cannot set maxTypeFactoryCacheSize to a negative value\");\n            }\n            _maxTypeFactoryCacheSize = maxTypeFactoryCacheSize;\n            return this;\n        }\n\n        /**\n         * Constructs a {@link DefaultCacheProvider} with the provided configuration values, using defaults where not specified.\n         *\n         * @return A {@link DefaultCacheProvider} instance with the specified configuration\n         */\n        public DefaultCacheProvider build() {\n            return new DefaultCacheProvider(_maxDeserializerCacheSize, _maxSerializerCacheSize, _maxTypeFactoryCacheSize);\n        }\n    }\n}\n","sourceCodeStart":184,"sourceCodeEnd":218,"githubUrl":"https://github.com/FasterXML/jackson-databind/blob/a50c7d2a1d57234ac4adf70dbd88ac90db6436e4/src/main/java/tools/jackson/databind/cfg/DefaultCacheProvider.java#L184-L218","documentation":"DefaultCacheProvider.Builder.maxTypeFactoryCacheSize(int) caps the TypeFactory's internal cache (which stores resolved JavaType instances) and throws IllegalArgumentException for negative values. Zero disables type caching (types are re-resolved each call, slower but unbounded in memory) while negative is rejected outright. This is the third symmetric guard alongside the serializer and deserializer cache caps.","triggerScenarios":"Calling builder.maxTypeFactoryCacheSize(-1) or any negative; deriving the value from a property or memory-budget calc that yields negative; a '-1 means unlimited' config convention passed through verbatim.","commonSituations":"Memory-budget-driven cache sizing that underflows; environment variable with a -1 default meaning 'auto'; 2.x-to-3.x migration where TypeFactory caching semantics changed and old sentinels are reused.","solutions":["Use 0 to disable type caching or a large positive int for 'effectively unlimited' (the default is already large; only lower it deliberately).","Validate at the config boundary and translate -1 -> a concrete large value.","If memory is the concern, prefer a modest positive cap (e.g. 4096) over disabling caching, since TypeFactory is on the hot path.","Add a test that the builder rejects negatives."],"exampleFix":"// before\nint tfCap = env.get(\"type.cache\", -1);\nDefaultCacheProvider.builder().maxTypeFactoryCacheSize(tfCap).build(); // throws\n// after\nint tfCap = env.getInt(\"type.cache\", 4096);\nif (tfCap < 0) tfCap = Integer.MAX_VALUE;\nDefaultCacheProvider.builder().maxTypeFactoryCacheSize(tfCap).build();","handlingStrategy":"validation","validationCode":"int cap = configuredTypeCache;\nif (cap < 0) throw new IllegalArgumentException(\"type cache < 0: \" + cap);\nDefaultCacheProvider.builder().maxTypeFactoryCacheSize(cap).build();","typeGuard":"// primitive int range check","tryCatchPattern":"try {\n    return DefaultCacheProvider.builder().maxTypeFactoryCacheSize(cap).build();\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"negative\")) {\n        return DefaultCacheProvider.builder().maxTypeFactoryCacheSize(0).build();\n    }\n    throw e;\n}","preventionTips":["Don't disable type caching casually — TypeFactory is hot; prefer a positive cap.","Validate external config and translate -1 -> large positive.","Document cache behavior in the config schema."],"tags":["cache","configuration","builder","type-system","validation"],"analyzedSha":"a50c7d2a1d57234ac4adf70dbd88ac90db6436e4","analyzedAt":"2026-08-06T20:31:51.404Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}