github open-metadata/OpenMetadata 2.0.2-release

pre-release12 hours ago

Changelog

OpenMetadata 2.0.2 is a maintenance release focused on connector reliability across Oracle, Databricks, Snowflake, BigQuery, Clickhouse, KafkaConnect, Grafana, and StarRocks, MCP tool consolidation and hardening, a governance rollout that restricts direct team membership to Group teams, several XSS and access-control fixes, and a broad security dependency cleanup.

🔌 Connectors & Ingestion

  • REST/OpenAPI: array properties with an inline object schema emitted a synthetic item: UNKNOWN child #32007: Expands the item's properties with their OpenMetadata types and descriptions instead.
  • REST/OpenAPI: API collections and endpoints could ingest out of order #31852: Persists all API collections before ingesting endpoints, so endpoints no longer reference a collection that hasn't been committed yet.
  • KafkaConnect: topic-namespace membership was emitted as lineage #32207: Topic-namespace membership is no longer misreported as a lineage edge.
  • KafkaConnect: Confluent Cloud managed connectors resolved no topics, and telemetry credential failures logged the same line whatever the cause #32512, #32999: Topics are now resolved from Confluent's Telemetry API, and the warning distinguishes a 401 from a 403 with Confluent's own error detail.
  • pygtrie 2.6 broke import airflow on Python 3.10 #32378: Caps pygtrie below 2.6 so ingestion imports Airflow correctly.
  • Databricks: SQL-defined DLT pipelines had no lineage extracted #31654: Lineage is now extracted from SQL-defined DLT pipelines.
  • Databricks: Unity Catalog access rows incorrectly linked a table to itself #32214: Legitimate access-not-derivation rows (a streaming or CDC write touching its own target table) no longer create a self-referencing lineage edge.
  • Databricks: large workspaces failed to ingest all jobs #33204: Jobs are now paginated by token, so large workspaces ingest in full.
  • Clickhouse: materialized views had no downstream lineage #32314: Downstream lineage is now created for materialized views.
  • Oracle: query history failed with ORA-00933 on Oracle 11g #32310: Query history now works against Oracle 11g.
  • Oracle: CHAR length semantics were lost in the reflected column type #32306: CHAR length semantics are now preserved during reflection.
  • Athena: assume-role credentials were never refreshed #32853: Assume-role credentials now refresh correctly.
  • Snowflake: query tags mutated the configured connection arguments #32481: QUERY_TAG is now applied through the driver session parameters at connection creation.
  • BigQuery: multi-project ingestion with ADC or a credentials file always connected to the first project #32846: Each database iteration is now scoped to the project it is ingesting.
  • Doris: identifiers in generated SQL were unquoted #32443: Doris identifiers are now quoted.
  • Grafana: panels nested inside collapsed rows were skipped #32825: Collapsed-row panels are flattened before chart and lineage ingestion.
  • Airflow: dynamically mapped tasks produced no lineage #32818: inlets/outlets serialized inside partial_kwargs are now read when the top-level keys are empty.
  • Protobuf schemas whose message didn't match the topic name failed to parse #32449: Parsing falls back to the sole top-level message, keeps ambiguous schemas unresolved, and supports well-known imports.
  • Domo and Astra connection fields diverged from the password-field conventions #32545: Both are aligned, and stored connection values are restored on update.
  • Kubernetes ingestion pipelines couldn't decrypt the ingestion-bot JWT token #32708: The token is now correctly deserialized and decrypted.
  • A bad SERVICE_TYPE_REF lookup result went unvalidated #32739: The result is now validated in get_reference_type_from_service_type.
  • The Kubernetes exit handler could match its own pod as the main pod #32743: The exit handler no longer matches itself.
  • Looker: data-model lineage failed on the first run #32367: The sink's bulk buffer is now flushed before anything looks up a data model.
  • Tableau: auto-titled mirror columns were ingested as duplicates #32301: Mirror columns are now collapsed.
  • Spark services offered a Metadata Agent that cannot work #32834: Spark metadata is pushed by the Spark Agent, so pull-based extraction is now marked unsupported.
  • StarRocks: lineage builds produced unresolvable FQNs #32543: FQNs now resolve correctly during lineage builds.

📊 Data Quality

  • Databricks profiler: remaining SQL failures #32441: Resolves the remaining SQL failures in the Databricks profiler.
  • The test case picker didn't handle request failures #32514: Request failures in the test case picker are now handled gracefully.
  • No way to soft delete and restore test cases #32349: Adds UI support for soft deleting and restoring test cases.
  • BigQuery: STRUCT profiler columns weren't attached #32549: STRUCT profiler columns are now attached correctly.
  • Doris: profiler datetime partition filters weren't Doris-compatible #32788: Adds Doris dialect compilation for DatetimeAddFn and TimestampAddFn.
  • Data Insights showed wrong numbers with no error, and one chart path returned a 500 #32115: Declares each data asset type once instead of in three separate places, fixing four silently-wrong metrics and the 500.
  • Sample-data validation timeout wasn't forwarded across docker exec #31710: The configured timeout now propagates correctly.
  • Contracts: qualityScore came back NaN when every referenced test was soft-deleted #32750: qualityScore no longer breaks when referenced tests are soft-deleted.
  • The contract status badge didn't reflect the actual status #32964: The badge is now driven off the actual contract status.
  • TestSuiteDetailsPage showed no error state on fetch failure #32746: A fetch failure now renders an error state instead of a blank page.
  • Profiler partitioning was built from stale form state #33117: Partitioning is now built from the current form values.
  • Auto-classification did nothing when sample data was disabled #32607: With no sampled fields, metadata leaf columns are now traversed so column-name recognizers still run.
  • Test Cases pagination wasn't reset when search or filters changed #33335: Pagination now resets to page one on search or filter changes.

🔍 Search & Discovery

  • name.keyword wasn't exposed, and removed search fields couldn't be re-added #32369: name.keyword is now exposed, and removed search fields can be re-added.
  • Embedding token usage was discarded instead of reported #32552: Embedding token usage is now reported.
  • Semantic search embedded ElasticSearch queries as documents instead of queries #32553: Queries are now embedded as queries, improving semantic search relevance.
  • A single-writer reindex pipeline was needed for RDF #33098: Backports a single-writer RDF reindex pipeline to prevent concurrent-write conflicts.
  • Ranking could throw an NPE on Lucene 10 when a segment had zero matches #33292: script_score now guards against zero-match segments.

🛡️ Data Governance & Quality

  • Governance workflow edge conditions and node references were interpolated unchecked into Flowable expressions #32370: Conditional-edge conditions and source nodes are now validated at the create/update boundary.
  • Direct users could be assigned to non-Group teams through the API or the team dropdown, then couldn't be removed, added through the UI, or exported #32372, #32915: Direct memberships are now rejected for Department, Division, and BusinessUnit teams, and team dropdowns offer only Group teams.
  • Migration: existing direct-user memberships on non-Group teams from before the fix above stayed invalid #33352: A 2.0.2 migration cleans up the pre-existing invalid memberships automatically.
  • Non-Group team Users tabs showed no members after direct membership was restricted #33354: The Users tab now rolls up members from sub-groups instead.
  • Bot list responses omitted the required botUser relationship #32398: The relationship is now batch-loaded for list responses, so SDK list_all_entities calls can deserialize Bot entities.
  • App endpoint permission checks didn't match the platform RBAC model #32427: App endpoints now align with platform RBAC, and App patch is authorized before the entity lookup.
  • Broken access control on the glossary-term bulk asset endpoints #32539: assets/add and assets/remove now authorize EDIT_GLOSSARY_TERMS on each target asset instead of bypassing the authorizer.
  • Cross-user follower changes were unrestricted #32322: Follower endpoints now reject a null userId, compare against the authenticated subject, and require admin authorization for cross-user mutations.
  • OpenMetadata accepted a URL without an http(s) scheme #32542: URLs without an http(s) scheme are now rejected.
  • Pub/Sub credentials weren't masked correctly #32135: Converts persisted Pub/Sub credentials to their generated schema classes before masking and unmasking, so they're consistently protected.
  • Overriding metadata merged tags instead of replacing them #32496: A bot bulk PUT that explicitly supplies tags now replaces existing tags when overrideMetadata is set, instead of merging them.
  • No way to export classification and tag-level data #31938: Adds export support for classification and tag level.
  • Bot searches didn't apply the caller's policies #32460: Bot searches now apply the caller's policies.
  • The search dropdown option label was set through dangerouslySetInnerHTML #32572: The highlighted label is parsed into React nodes from a sanitized string instead.
  • stringToHTML rendered stored user content unsanitized #32951: The helper now routes through DOMPurify.sanitize().
  • A DOMPurify bypass in math equations, and an XSS in the mention dropdown #32896: Both are closed.
  • Airflow API responses leaked internal diagnostics #32850: Responses are now generic. Diagnostics remain in the logs.

🔗 Lineage

  • Impact Analysis pagination wasn't reset when search or quick-filters changed #32699: Pagination now resets to page one.
  • Changing the Upstream/Downstream Depth in the lineage settings modal did nothing #33299: The setting now writes to the shared lineage store, so changing it correctly refetches the graph.

🤖 MCP Server / Automations

  • The MCP tool surface had 24 overlapping tools #32072: Merges overlapping tools down to 15.
  • MCP Knowledge Page creation was broken #32209: Knowledge Page creation now works through MCP.
  • MCP mishandled unknown methods and initialized notifications #32147: Both are now handled per the MCP protocol.
  • MCP tools bypassed lineage authorization #32437: Lineage authorization is now enforced in MCP tools.
  • MCP entity patch requests mishandled the entity lifecycle #32226: MCP entity patch lifecycle handling is fixed.
  • The MCP connector used an unsupported ingestion transport #32342: The MCP connector now uses HTTP transport.
  • An owner could be rejected with a 403 reading their own private memory #32858: The owners relationship is now hydrated before the private-memory visibility check runs, even when the request didn't project owners.
  • AI context trust signals and MCP context-memory visibility were missing #32261, #32465: Both are added.

🔐 Authentication

  • SSO role changes at the identity provider weren't reflected in OpenMetadata #32961: SSO roles now sync from the provider's id_token at the OIDC callback.
  • OIDC login could issue a zero-lifetime token #33251: Zero-lifetime OIDC login tokens are now prevented.

⚙️ Platform

  • catalog.log duplicated every rotated openmetadata.log line #32366: Log rotation no longer duplicates lines into catalog.log.
  • Logs failed to render on Kubernetes 1.36+ #32504: Logs now render correctly on Kubernetes 1.36 and later.

🎛️ UI

  • The Queries tab showed the parent table's description provenance instead of its own #32292: The Queries tab now shows the correct provenance.
  • A second domain tag update returned a 400 #32358: A second update to a domain tag no longer fails.
  • No pagination for large glossaries #32223: Adds cursor-based Prev/Next pagination and paged expand-all for glossary terms.
  • Math equations were silently stripped on save #32313: Preserves <block-math-equation> nodes through both the frontend and backend sanitizers.
  • The metric version page crashed into the error boundary #32794: UnitOfMeasurement was a type-only import, so it was erased at build time and threw at runtime. It's now imported as a value.
  • The Data Product "Add Assets" picker ignored the Domain Validation rule #32336: The picker lists assets across all domains when the rule is disabled, and stays domain-scoped when it's enabled.
  • The glossary term-not-found state used an inconsistent placeholder #32865: The term-not-found state now uses the shared NoDataPlaceholder component.
  • No way to filter team assets by entity type, and quick-filter removal was broken #32807: Adds an Entity Type filter to team assets and fixes quick-filter removal.
  • The Data Product Reviewers field showed in OSS #32914: The field is now hidden in OSS, since it's a Collate-only capability.
  • The Data Product grid card had no Description field #32948: Adds a Description field to the grid card and restyles its labels.
  • The Glossary Terms zero-result state ignored active filters #32857: The empty state is now filter-aware.
  • The entity-type trigger didn't receive focus before its listbox opened #32969: Focus now moves to the trigger first.
  • Context Center: the article Data Products panel and domain save had bugs #33081: Both are fixed.
  • Advanced Search lowercased tag-like option casing #33220: Tag-like options now show their original casing.
  • The entity hover card could outlive its trigger, and a 403 looked identical to an empty result #33205: The hover card now closes when its trigger is gone, and a 403 is now told apart from a genuinely empty response.
  • The Topic page showed nothing on sustained fetch failures #32736: The Topic page now shows an error placeholder.
  • TierCard's selected tier wasn't reset on close #33115: Closing the card now resets selectedTier, preventing stale radio state.
  • The table-type custom property editor lost user data when a column was named id #32741: User data is now preserved regardless of column name.
  • Clicks on Domain and Data Product listing rows could be intercepted by a nested link or an overlay #33267, #33022: Row clicks and the pointer cursor now work correctly, and overlays no longer swallow clicks meant for the row.

🔒 Security

  • @humanfs/node → 0.16.8 #32561.
  • Jackson for CVE-2026-83557 and CVE-2026-19032 #32813.
  • fast-uri → 3.1.7 #32870.
  • js-yaml → 5.4.1 #32913.
  • Jetty → 12.1.12 #33026.
  • @tiptap/* → 2.27.3 for a mergeAttributes prototype-pollution vulnerability #33035.
  • Vulnerable Debian packages upgraded in ingestion images #33321.
  • Netty → 4.2.18.Final and Freemarker → 2.3.35 for CVE-2026-89044 and CVE-2026-84939 #33327.

📣 Notifications

  • Bulk entity updates wrote no change event, so Get Schema Changes alerts never fired on metadata ingestion #32350: The bulk path now captures the incremental change description, so bulk updates both alert and audit.
  • A Pipeline alert filtered to Failed re-notified forever and backfilled on creation #32181: Re-ingested and historical runs no longer emit change events.
  • A single unevaluable event discarded its whole change-event batch #32953: One bad event no longer takes down the rest of the batch.

Full Changelog: 2.0.1...2.0.2

Don't miss a new OpenMetadata release

NewReleases is sending notifications on new releases.