apache/druid · error · ISE

Failed to deserialize a DB object

Error message

Failed to deserialize a DB object

What it means

fromBytes deserializes a BLOB column (properties/columns JSON) from the catalog tables into Java objects using Jackson. If the stored bytes are not valid JSON or don't match the expected TypeReference, it wraps the IOException in this ISE. It almost always means corrupt or incompatible data in the metadata DB.

Source

Thrown at extensions-core/druid-catalog/src/main/java/org/apache/druid/catalog/storage/sql/SQLCatalogManager.java:747

  private NotFoundException tableNotFound(TableId id)
  {
    return new NotFoundException(
        "Table %s: not found",
        id.sqlName()
    );
  }

  /**
   * Deserialize an object from an array of bytes. Use when the object is
   * known deserializable so that the Jackson exception can be suppressed.
   */
  private static <T> T fromBytes(ObjectMapper jsonMapper, byte[] bytes, TypeReference<T> typeRef)
  {
    try {
      return jsonMapper.readValue(bytes, typeRef);
    }
    catch (IOException e) {
      throw new ISE(e, "Failed to deserialize a DB object");
    }
  }

  private static TableSpec tableSpecFromBytes(
      final ObjectMapper jsonMapper,
      final String type,
      final byte[] properties,
      final byte[] columns
  )
  {
    return new TableSpec(
        type,
        properties == null ? null : propertiesFromBytes(jsonMapper, properties),
        columns == null ? null : columnsFromBytes(jsonMapper, columns)
    );
  }

  private static final TypeReference<Map<String, Object>> PROPERTIES_TYPE_REF = new TypeReference<>() {};

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Inspect the offending row's blob in the DB and repair or delete the malformed row.
  2. Restore the metadata DB from backup if corruption is widespread.
  3. Confirm the Druid version reading the table matches the version that wrote it; migrate data if schemas changed.
  4. If a single table is bad, drop and re-create it through the catalog API.

Example fix

// diagnosis: find the bad row, then fix via API
// before: corrupted row causes ISE on every read
// after
dbi.update("DELETE FROM druid_catalog_tables WHERE table_name = ?", badTable);
manager.createTable(id, rebuiltSpec);
Defensive patterns

Strategy: try-catch

Try / catch

try {
  TableMetadata t = manager.readTable(id);
} catch (ISE e) {
  if (e.getMessage().contains("Failed to deserialize a DB object")) {
    // flag row as corrupt; repair DB or restore from backup
  }
}

Prevention

When it happens

Trigger: Any read path (readTable, listTableNames, etc.) deserializing a DB row whose properties/columns blob was written by an incompatible Druid version, hand-edited, truncated, or otherwise not parseable into TableSpec/TableProperties.

Common situations: Upgraded Druid reading catalog rows written by an older/newer schema; manual UPDATE of DB blobs; DB corruption or byte truncation; inserting rows via external tooling with wrong serialization.

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/b5b38c13ef077b6e. Report an issue: GitHub.