apereo/cas · warning

Object value [ ] assigned to [ ] is not serializable and…

Error message

Object value [{}] assigned to [{}] is not serializable and may not be part of the ticket [{}]

What it means

TicketRegistrySessionStore.set stores pac4j session values as properties on a transient session ticket, which requires values to be Serializable. When the value set for a session key is neither null nor java.io.Serializable, it cannot be attached to the ticket, so this warning is logged and the value is effectively dropped (not persisted).

Solutions

  1. Make the stored value Serializable (implement java.io.Serializable on its class, or store a serializable DTO/String instead).
  2. Convert the value to a serializable representation (e.g. JSON string) before calling set().
  3. If the value is intentionally transient, ignore the warning or avoid putting that key in the ticket-backed session store.

Example fix

// before
sessionStore.set(ctx, "cart", new Cart(...)); // Cart not Serializable
// after
public class Cart implements java.io.Serializable { ... }
sessionStore.set(ctx, "cart", cart);
Defensive patterns

Strategy: type-guard

Validate before calling

if (value == null || value instanceof java.io.Serializable) { sessionStore.set(ctx, key, value); } else { sessionStore.set(ctx, key, serializeToJson(value)); }

Type guard

static boolean isStorable(Object v) { return v == null || v instanceof java.io.Serializable; }

Prevention

When it happens

Trigger: Calling TicketRegistrySessionStore.set(context, key, value) with a non-Serializable object as value during delegated (pac4j) authentication session data handling.

Common situations: Custom pac4j clients or profile/authorization code storing complex (non-Serializable) objects in the session store; library upgrades introducing new session values that are not Serializable; storing request-bound objects in the distributed session.

Understand the failure class

Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/325c9f91cc1c3ea4. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-pac4j-api/src/main/java/org/apereo/cas/pac4j/TicketRegistrySessionStore.java:68

            return Optional.empty();
        }
        return Optional.ofNullable(ticket.getProperties().get(key));
    }

    @Override
    public void set(final WebContext context, final String key, final Object value) {
        LOGGER.trace("Setting key: [{}]", key);
        val sessionId = getSessionId(context, true).orElseGet(() -> {
            val newSessionId = UUID.randomUUID().toString();
            LOGGER.trace("Generated session id: [{}]", newSessionId);
            return newSessionId;
        });

        val properties = new HashMap<String, Serializable>();
        if (value instanceof final Serializable serializable) {
            properties.put(key, serializable);
        } else if (value != null) {
            LOGGER.warn("Object value [{}] assigned to [{}] is not serializable and may not be part of the ticket [{}]", value, key, sessionId);
        }
        
        val ticket = getTransientSessionTicketForSession(context);

        if (value == null && ticket != null) {
            ticket.getProperties().remove(key);
            updateTicket(context, ticket);
        } else if (ticket == null) {
            FunctionUtils.doAndHandle(_ -> {
                val transientFactory = (TransientSessionTicketFactory) ticketFactory.get(TransientSessionTicket.class);
                val transientSessionTicket = transientFactory.create(sessionId, properties);
                val addedTicket = ticketRegistry.addTicket(transientSessionTicket);
                
                val webContext = (JEEContext) context;
                cookieGenerator.addCookie(webContext.getNativeRequest(), webContext.getNativeResponse(), addedTicket.getId());

                context.setRequestAttribute(SESSION_ID_IN_REQUEST_ATTRIBUTE, addedTicket.getId());
            });

View on GitHub (pinned to e7288fc434)