{"record":{"id":"912cc4c1805d222e","repo":"apolloconfig/apollo","slug":"spring-session-json-serializing-error-this-is-usu","errorCode":null,"errorMessage":"Spring-session JSON serializing error, This is usually caused by the system upgrade, please clear the browser cookies and try again.","messagePattern":"Spring-session JSON serializing error, This is usually caused by the system upgrade, please clear the browser cookies and try again\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":500,"severity":"error","filePath":"apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/component/config/SpringSessionConfig.java","lineNumber":51,"sourceCode":" *\n * @author kl (http://kailing.pub)\n * @since 2022/7/26\n */\n@Configuration\npublic class SpringSessionConfig implements BeanClassLoaderAware {\n\n  private ClassLoader loader;\n\n  @Bean(\"springSessionConversionService\")\n  @ConditionalOnProperty(prefix = \"spring.session\", name = \"store-type\", havingValue = \"jdbc\")\n  public ConversionService springSessionConversionService() {\n    GenericConversionService conversionService = new GenericConversionService();\n    ObjectMapper objectMapper = this.objectMapper();\n    conversionService.addConverter(Object.class, byte[].class, source -> {\n      try {\n        return objectMapper.writeValueAsBytes(source);\n      } catch (IOException e) {\n        throw new RuntimeException(\n            \"Spring-session JSON serializing error, This is usually caused by the system upgrade, please clear the browser cookies and try again.\",\n            e);\n      }\n    });\n\n    conversionService.addConverter(byte[].class, Object.class, source -> {\n      try {\n        return objectMapper.readValue(source, Object.class);\n      } catch (IOException e) {\n        throw new RuntimeException(\n            \"Spring-session JSON deserializing error, This is usually caused by the system upgrade, please clear the browser cookies and try again.\",\n            e);\n      }\n    });\n    return conversionService;\n  }\n\n  @Bean(\"springSessionDefaultRedisSerializer\")","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/apolloconfig/apollo/blob/d95fc18d112589efc09ddcbe1507047584d55251/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/component/config/SpringSessionConfig.java#L33-L69","documentation":"Thrown inside the JDBC-backed Spring-session converter registered by SpringSessionConfig. The converter calls objectMapper.writeValueAsBytes(source) to turn a session attribute (Object) into a byte[] for the SPRING_SESSION table; if Jackson raises an IOException it is wrapped in this RuntimeException (HTTP 500). The message points at a version upgrade because the most common root cause is an incompatible class shape read back from an older session row.","triggerScenarios":"Any portal request that mutates the HTTP session (login, role/permission grant, logout) while spring.session.store-type=jdbc AND a session attribute is a type Jackson cannot serialize (missing no-arg ctor, polymorphic type without @JsonTypeInfo, circular ref).","commonSituations":"Upgrading Apollo portal across versions where session attribute classes changed package/shape; storing a custom non-serializable object in the session; a corrupted or half-migrated SPRING_SESSION row left from a previous deploy.","solutions":["Clear browser cookies (or the SPRING_SESSION / SPRING_SESSION_ATTRIBUTES rows for that session id) so the stale attribute is discarded, then log in again.","Inspect the wrapped IOException in the portal log stack trace to find the exact attribute type that fails serialization.","If a custom object is the culprit, make it Jackson-serializable (no-arg constructor, or register a mix-in / ObjectMapper config consistent with SpringSessionConfig.objectMapper()).","During a planned upgrade, flush active sessions on both portal and its session DB to avoid mixing old and new attribute shapes."],"exampleFix":"// before: polymorphic object in session breaks Jackson\nsession.setAttribute(\"ctx\", someUntypedObject);\n\n// after: store a Jackson-friendly DTO with a no-arg ctor and explicit type\nsession.setAttribute(\"ctx\", new ContextDTO(someUntypedObject));","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Portal API client: any session-mutating call can 500 with this message on a stale session.\ntry {\n  portal.login(credentials);\n} catch (HttpServerErrorException e) {\n  if (e.getResponseBodyAsString().contains(\"Spring-session JSON serializing error\")) {\n    clearPortalCookies();          // drop the local JSESSIONID\n    purgeServerSessionRow();       // optional: delete SPRING_SESSION row\n    portal.login(credentials);     // fresh session\n  } else { throw e; }\n}","preventionTips":["Flush active sessions (portal + session DB) during every portal upgrade.","Do not place custom non-serializable objects into the HTTP session.","Keep the ObjectMapper in SpringSessionConfig stable across releases.","Log and alert on the wrapped IOException to catch the failing attribute early."],"tags":["spring-session","serialization","jdbc","jackson","session","upgrade"],"backgroundTag":null,"analyzedSha":"d95fc18d112589efc09ddcbe1507047584d55251","analyzedAt":"2026-08-14T04:00:05.477Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}