apache/druid · error · RuntimeException

Failed to deserialize object

Error message

Failed to deserialize object

What it means

Pac4jSessionStore.deserializeFromBytes uses ObjectInputStream to rebuild the user profile from cookie bytes. IOException or ClassNotFoundException means the data is corrupt, was tampered with, or was serialized with classes not present on the current classpath (e.g. after an upgrade or extension removal).

Solutions

  1. Treat deserialization failure as 'no session' and force re-login (catch and clear cookie)
  2. Keep profile classes and serialVersionUID stable across releases
  3. Ensure the same pac4j extension versions are deployed cluster-wide
  4. Prefer JSON-based profile serialization to avoid classpath coupling

Example fix

// before
return store.uncompressDecryptBase64(cookieValue);
// after
try {
  return store.uncompressDecryptBase64(cookieValue);
} catch (RuntimeException e) {
  securityLogger.warn(e, "Could not restore session from cookie");
  return null;
}
Defensive patterns

Strategy: try-catch

Try / catch

try { profile = store.uncompressDecryptBase64(cookie); } catch (RuntimeException e) { LOGGER.warn(e, "Cannot deserialize session cookie; forcing re-login"); clearCookie(); profile = null; }

Prevention

When it happens

Trigger: Calling uncompressDecryptBase64 on cookie bytes whose serialized classes no longer exist (class renames, removed extension, different pac4j version), or bytes corrupted by key change/truncation.

Common situations: Upgrading Druid or pac4j so stored session classes changed serialVersionUID or package; profile class moved between extensions; corrupt/tampered cookies.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/67a541475931445c. Report an issue: GitHub.

Appendix: source

Thrown at extensions-core/druid-pac4j/src/main/java/org/apache/druid/security/pac4j/Pac4jSessionStore.java:282

    }
    catch (IOException e) {
      throw new RuntimeException("Failed to serialize object", e);
    }
  }

  /**
   * Deserialize object using standard Java serialization
   */
  private Serializable deserializeFromBytes(byte[] data)
  {
    Preconditions.checkNotNull(data, "Data to deserialize cannot be null");

    try (ByteArrayInputStream bais = new ByteArrayInputStream(data);
         ObjectInputStream ois = new ObjectInputStream(bais)) {
      return (Serializable) ois.readObject();
    }
    catch (IOException | ClassNotFoundException e) {
      throw new RuntimeException("Failed to deserialize object", e);
    }
  }

  /**
   * Clear sensitive data from user profiles before storing in cookies
   */
  private Object clearUserProfile(final Object value)
  {
    if (value instanceof Map<?, ?>) {
      final Map<String, CommonProfile> profiles = (Map<String, CommonProfile>) value;
      profiles.forEach((name, profile) -> {
        // In pac4j 5.x, we need to manually clear sensitive data
        // since removeLoginData() is no longer available
        if (profile != null) {
          profile.removeAttribute("access_token");
          profile.removeAttribute("refresh_token");
          profile.removeAttribute("id_token");
          profile.removeAttribute("credentials");

View on GitHub (pinned to 9b90983fd2)