• Concept
  • Release notes

6.0.0 Secure Release Notes

What's new

What's new at a glance

Continuity from Liquibase Secure 5.x

The Liquibase Secure platform

Liquibase Secure CLI

Liquibase Secure Server

Change Intelligence

One view across the database estate

From signal to root cause, fast

Optional, on-demand AI Analysis with your own model

Catch drift early

Audit ready by design

Change Governance

Policies: catalogs, packages, and checks

Assignments: policy without pipeline changes

Adopt incrementally

Built for shared ownership

Change Automation

Database Connectors: cloud authentication and secrets management

IAM authentication for Amazon RDS and Aurora
IAM authentication and Secret Manager for Google Cloud
Azure Key Vault secrets
Mixed authentication for target and reference databases

Changeset targeting and filtering

New changeset attributes: teams, releases, keywords, and conditions
Checks Targeting

Policy checks

Run checks from a Change Governance Assignment
Stricter validation and partial customization
Shared modules for custom Python checks
More accurate results and attribution, better performance

Changelog generation

One file per table with object changelogs
Generated changelogs that match the schema

Database support

PostgreSQL
MongoDB
Amazon DynamoDB
Couchbase
MySQL, MariaDB, and SQL Server

Performance

Faster on large schemas

CLI output and logging

Machine-readable STDOUT, human-readable STDERR
Control verbosity, see what changed
Logging that stays out of your application’s way
Credentials and SQL handled as written
Error codes and exit codes

Developer Productivity

Liquibase Secure Developer for VS Code

Liquibase AI Changelog Generator

Deployment Connectors

Security: SSO and RBAC

Authentication and single sign-on

API tokens and service principals

Role-based access control

Action required when you upgrade

Security vulnerability report

CVE summary

Full list of changes

  • Cloud Authentication(INT-1960, INT-2034, INT-2035) You can now connect to AWS Aurora and Amazon RDS databases (PostgreSQL and MySQL) using IAM database authentication. Set your password value to aws-rds-iam and Liquibase generates a short-lived IAM token for each connection instead of using a static password. You can supply the AWS region with liquibase.rds.iam.region and connect across accounts by assuming a role with liquibase.rds.iam.roleArn. SSL must be enabled on the connection.
  • Cloud Authentication(INT-2044, INT-2045) You can now connect to GCP Cloud SQL for PostgreSQL using IAM database authentication in the new Liquibase GCP extension. Set your password value to gcp-cloudsql-iam and Liquibase authenticates through the Google Cloud SQL Java Connector, so you no longer need the Cloud SQL Auth Proxy. You can impersonate a service account with liquibase.cloudsql.targetServiceAccount, and connection problems now surface as clear error messages.
  • Cloud Authentication(INT-2056) You can also authenticate to GCP Cloud SQL by minting a short-lived OAuth2 token and passing it as the database password (password: gcp-cloudsql-iam-token), for both PostgreSQL and MySQL. This is a lighter alternative to the connector and works over a standard JDBC connection through the Cloud SQL Auth Proxy. It requires SSL on the JDBC URL, or the token travels in plaintext.
  • Cloud Authentication(INT-2058) You can now resolve configuration values such as password, url, or username from Google Secret Manager using a gcp-secret-manager,<reference> prefix. This mirrors the existing aws-secrets modifier and works with a full resource name or a shorthand name resolved against your default GCP project.
  • Cloud Authentication(INT-2186, INT-2187, INT-2188) You can now pull secrets, public keys, and certificates from Azure Key Vault, so you can keep values like your database password out of your Liquibase configuration and let Liquibase retrieve them with your existing Azure credentials.
  • Cloud Authentication(INT-2211) You can now use different authentication mechanisms for the target and reference databases when running diff or diff-changelog on Snowflake, Databricks, MongoDB, and AWS RDS. Each platform's auth selector now has reference-scoped counterparts, so your target database can use key-pair, OAuth, OIDC, or IAM authentication while a legacy reference database still signs in with a password. Set these keys in your defaults file, as environment variables, or as Java system properties. They are not accepted as command-line flags.
  • Change Targeting and Policy Checks(SECURE-98) Liquibase now supports four new changeset attributes (teams, releases, keywords, and conditions) that you can use to tag your changesets and filter which ones run with the matching --teams-filter, --releases-filter, --keywords-filter, and --conditions-filter flags, so you have more precise targeting without overloading labels and contexts.
  • Change Targeting and Policy Checks(SECURE-503) You can now use the @ symbol to force strict matching in teams-filter, releases-filter, keywords-filter, and conditions-filter, the same way it already works with label-filter and context-filter. Putting @ in front of a value (for example, --teams-filter=@frontend) runs only changesets with exactly that value. You can combine filters too, so --teams-filter=@frontend --releases-filter=v1 runs only changesets tagged with both.
  • Change Targeting and Policy Checks(SECURE-100) Checks targeting lets you set persistent ignore or include rules for checks run, so you can skip or exclusively inspect specific changesets with a given check without disabling the check or editing your changelog.
  • Change Targeting and Policy Checks(SECURE-152) Running validate --strict now validates the teams, releases, keywords, and conditions attributes, so you can catch typos and empty values before they cause problems at deploy time.
  • Change Targeting and Policy Checks(SECURE-105) Running validate --strict now catches invalid property names in include and includeAll blocks, so typos or unrecognized attributes are reported before they cause unexpected behavior.
  • Change Targeting and Policy Checks(SECURE-101) You can now update individual check properties with checks customize --configs without specifying every parameter, so you can change just the severity or message without rebuilding the full check.
  • Change Targeting and Policy Checks(DAT-22576) Custom policy check Python scripts can now import shared modules from other directories and from sibling files. A new --checks-scripts-python-path argument adds directories to the Python import path, and the script's own directory is added automatically. When the option is not set, existing behavior is unchanged.
  • Change Targeting and Policy Checks(SECURE-479) Liquibase now applies custom regular-expression policy checks statement by statement, so checks run completes quickly on large SQL changesets that previously caused it to stall.
  • Change Targeting and Policy Checks(SECURE-89) Keyword-based checks such as SqlGrantWarn, SqlRevokeWarn, and WarnOnUseDatabase no longer flag DML statements when reserved words appear as data values. For example, an INSERT with an address like 101 Grant St. no longer triggers SqlGrantWarn. These checks now only flag DDL and DCL statements.
  • Change Targeting and Policy Checks(SECURE-44, SECURE-45, SECURE-46, SECURE-47) Liquibase now validates parameter values immediately when you run checks customize in headless mode, with or without --configs, and tells you the allowed options instead of hanging, crashing, or saving a configuration that fails later.
  • Change Targeting and Policy Checks(SECURE-41) Changelog-scoped policy checks no longer appear in your results when you run checks run --checks-scope=DATABASE.
  • Change Targeting and Policy Checks(SECURE-53) Liquibase now correctly strips // comments from MongoDB formatted changesets when you use strip_comments() in a custom policy check.
  • Change Targeting and Policy Checks(SECURE-346) SqlUserDefinedPatternCheck findings on large changesets now include the matched text and line number, consistent with findings on smaller changesets.
  • Change Targeting and Policy Checks(SECURE-372) Liquibase now rejects duplicate object type values when you customize a check (for example, TABLE,TABLE) and ignores duplicates already saved, so each violation appears once in the console output.
  • Change Targeting and Policy Checks(DAT-21274) Fixed an issue where the Checks Report showed the OPERATOR = EQUALS parameter once per violation for ReservedKeywords checks. On large changelogs, the accumulated duplicates inflated the report and could cause out-of-memory failures. This issue was present in Liquibase Secure 5.1.1.
  • Change Targeting and Policy Checks(SECURE-490) Running liquibase checks describe now shows you every valid option for a check right alongside its current settings, with no extra flag required. For each configurable parameter, you'll see the default value next to what it's currently set to, along with the full list of valid choices, and every check reports its complete set of severity levels and enabled and disabled options. Whether you're building a GUI panel for check configuration or just exploring what's available, you get the full picture every time you run the command.
  • Change Targeting and Policy Checks(INT-2142) RedshiftDatabase now extends the new AbstractPostgresDatabase class instead of PostgresDatabase. If your custom extension uses instanceof PostgresDatabase to detect Amazon Redshift, that check no longer matches. Use instanceof AbstractPostgresDatabase to detect any Postgres-family database. Real PostgreSQL connections are not affected. snapshot and generate-changelog now work on Amazon Redshift. They previously failed with function array_position(smallint[], smallint) does not exist.
  • Change Targeting and Policy Checks(SECURE-547) Policy checks based on SQL patterns (such as checks for ALTER INDEX or CREATE TABLE) no longer take minutes to run against changelogs containing large multi-value INSERT statements, so your checks pipeline finishes in seconds instead of hours. This issue was present in Liquibase Secure 5.1.0.
  • Change Targeting and Policy Checks(SECURE-49) Liquibase now correctly attributes policy check violations in the checks report when you use checks packages with multiple configuration files, so violations are no longer counted multiple times or shown under the wrong configuration file
  • Change Targeting and Policy Checks(SECURE-95) If you used PII or PHI checks against DynamoDB changesets written in YAML or JSON, insert and put statements weren't being scanned, so the check could report no violations even when identifiers like STREET_ADDRESS were present in your data (changesets in XML weren't affected). This has been fixed, so PII and PHI checks now scan DynamoDB PartiQL changesets consistently across YAML, JSON, and XML changelog formats.
  • Change Targeting and Policy Checks(SECURE-655) checks run and checks show accept a new --assignment-id parameter, which points the command at a checks assignment configured in Governance instead of at a local checks settings file. Separate several assignment IDs with commas. --checks-settings-file continues to work, and checks that come from an assignment are read-only in the CLI.
  • Change Targeting and Policy Checks(SECURE-607) status --verbose now reports the teams, releases, keywords, and conditions changeset attributes alongside the ones it already showed, so you can see which changesets carry them without opening the changelog.
  • Change Targeting and Policy Checks(GOV-5) Liquibase 6 adds a governance interface for policy checks. You can browse the checks that ship with Liquibase, import a checks settings file you already have, organize checks into packages and catalogs, and change a check's parameters, all in the web interface rather than in a file. Copying a shipped check and customizing the copy keeps the original intact. Assignments connect that configuration to a run. You pick the checks you want and the things you want them to run against, choosing from your workspace, projects, pipelines, database connections, and changelogs, and Liquibase gives the assignment an ID. Passing --assignment-id=<UUID> to liquibase checks run collects that assignment's checks from Liquibase and runs them, so a pipeline no longer needs a checks settings file on disk. Comma-separate the IDs to run more than one assignment. Two teams can hold separate assignments against the same pipeline and run them independently, so a long compliance sweep does not block a short coding-standards check. The checks settings file continues to work exactly as before. Saving an assignment tells you what the change affects before it is applied. Assignments and check configurations both keep a version history, and you can restore an earlier version.
  • Change Targeting and Policy Checks(SECURE-706) When a policy check triggers on a changeset that a checks targeting rule affects, checks run console output at INFO level now includes the targeting file path, whether the rule is EXEMPT or RESTRICT, and, when set, the rule's reason and expiration. Previously this information only appeared in the HTML report, so teams who read console logs instead of the report can now see which targeting rules affected a run's results.
  • Change Targeting and Policy Checks(SECURE-712) A new liquibase checks export command bundles a checks package, and optionally its linked checks-settings files and Python check scripts, into a single archive so you can migrate your policy checks configuration into Change Governance. Choose the archive type with --format (zip by default, or tar, targz), and use --linked-checks-files and --python-scripts to choose whether those files are packaged into the archive or left as file path references. In this release, liquibase checks export only builds the archive. You still import it into Change Governance yourself.
  • Change Targeting and Policy Checks(SECURE-612) checks describe now reports the secondary parameters that a mode-select value brings into play, such as COLLECTION_NAME on MongoChangetypeAttributes or BILLING_MODE on DynamoChangetypeAttributes, along with the values you configured, so it matches what checks show already displayed. This issue was present in Liquibase Secure 5.2.0-5.2.2.
  • Performance(SECURE-267, DAT-22345, DAT-22346, DAT-22348, DAT-22349, DAT-22350) Liquibase now completes snapshot, diff, and generate-changelog significantly faster on large schemas across PostgreSQL, SQL Server, MySQL, MariaDB, Db2, Databricks, and BigQuery.
  • Performance(SECURE-499, SECURE-553) Taking a snapshot of a MySQL or MariaDB database with many stored procedures and functions is now significantly faster. Liquibase fetches those definitions in parallel instead of one at a time, reducing snapshot time by roughly 25 to 30 percent on very large schemas, with identical content. The speedup also applies to generate-changelog, diff-changelog, and, on your target database, diff. It applies to CLI runs. Maven plugin runs currently use the serial path and produce the same results.
  • Performance(SECURE-454) If you ran diff against a large schema, Liquibase previously repeated the same environment variable and system property lookups for every object it compared, instead of doing it once. This has been resolved, so diff now reuses the same caching Liquibase already applies elsewhere, making your comparisons on large schemas noticeably faster with no change to the results you get.
  • Performance(SECURE-464) Liquibase no longer prints command output to your console by default when you embed it in your own application (for example a Spring Boot app).
  • Performance(SECURE-790) validate and checks run --checks-scope=changelog no longer fail with OutOfMemoryError: Java heap space on a formatted-SQL changelog that ends in a large block comment.
  • Changelog Generation and Snapshot(SECURE-309) You can now generate changelogs organized as one file per table by passing --object-changelogs=by-table to generate-changelog or diff-changelog, so a table and everything tied to it lands in a single file instead of being scattered across per-type folders.
  • Changelog Generation and Snapshot(SECURE-556) If you name your changelog file without a database type segment (for example, changelog.sql instead of changelog.snowflake.sql), generate-changelog now figures out the right SQL dialect from the database you connect to. Your per-object SQL files follow the same convention. If your filename already includes a segment, nothing changes.
  • Changelog Generation and Snapshot(SECURE-92) Liquibase update reports now hide the detail rows for skipped changesets while still showing the total skipped count in the summary, so reports stay readable even when hundreds of changesets are filtered out.
  • Changelog Generation and Snapshot(INT-1847) Snowflake sequence snapshots now capture the ordered (ORDER/NOORDER) and comment properties across snapshot, diff, diff-changelog, and generate-changelog, which previously dropped them. Regenerate any existing Snowflake snapshots that include sequences, because older snapshots are missing these properties and will produce incorrect diff results.
  • Changelog Generation and Snapshot(INT-1914) Fixed an issue where generate-changelog with --should-snapshot-data=true against Snowflake silently ignored the setting and captured no row data. Row data is now captured as insert changesets in objects/inserts/ sub-changelogs, matching other databases.
  • Changelog Generation and Snapshot(INT-1916) Fixed an issue where MongoDB snapshots captured only an index's key definition, name, and unique flag, dropping 13 other attributes including expireAfterSeconds (TTL), sparse, partialFilterExpression, collation, hidden, and text index settings. These attributes are now captured and round-trip correctly. This issue was present in Liquibase Secure 5.1.0.
  • Changelog Generation and Snapshot(INT-1949) Fixed an issue where a formatted SQL changelog generated from a Snowflake schema with Dynamic Tables embedded a trailing semicolon in the query body, causing diff to report a false query change after deploying the generated changelog.
  • Changelog Generation and Snapshot(INT-2010) Liquibase now generates MongoDB changelogs with views in dependency order, fixing an issue in 5.2.0 where a view could appear before the collections and views it relies on.
  • Changelog Generation and Snapshot(INT-2041) Fixed a bug where --should-snapshot-data=true was silently ignored during generate-changelog on Databricks, omitting row data without warning.
  • Changelog Generation and Snapshot(INT-2077) Liquibase now excludes its own MongoDB tracking collections (DATABASECHANGELOG, DATABASECHANGELOGLOCK, and DATABASECHANGELOGHISTORY) from snapshot, diff, generate-changelog, and diff-changelog, fixing an issue in 5.2 where these collections showed up as drift. Regenerate snapshots captured before this release for clean results.
  • Changelog Generation and Snapshot(INT-2213) Fixed an issue where diff-changelog with diffTypes=compositetype did not detect differences in composite type attribute data types, so real schema differences were silently omitted from the generated changelog.
  • Changelog Generation and Snapshot(INT-1771) Fixed an inconsistency in the "Database objects Validated" summary when running checks run --checks-scope=database against Snowflake. Liquibase tracking tables are now excluded from the count, and view columns are now included, matching other databases.
  • Changelog Generation and Snapshot(INT-1846) Deploying pro-snowflake:createDynamicTable against a non-Snowflake database now fails validation with a clear error instead of silently creating a regular table and dropping Dynamic Table attributes like targetLag, refreshMode, and warehouse.
  • Changelog Generation and Snapshot(INT-1319) Fixed an issue where enabling the DATABASECHANGELOGHISTORY table on Redshift caused update to fail with value too long for type character varying(256). The EXECUTEDSQL and EXTENSIONS columns are now VARCHAR(65535) on Redshift, and existing history tables migrate automatically on the next update. This issue was present in every released version up to and including Liquibase Secure 5.2.2.
  • Changelog Generation and Snapshot(SECURE-286) Liquibase now correctly preserves STRING(65535) column types when generating a changelog from BigQuery, instead of dropping the length to bare STRING.
  • Changelog Generation and Snapshot(SECURE-483) Snapshot output for MySQL and MariaDB is now more consistent. Column type names are reported in standard uppercase JDBC format (for example, VARCHAR instead of varchar), and stored function definitions preserve their CHARSET clause, improving comparison across releases.
  • Changelog Generation and Snapshot(SECURE-485) Fixed a regression where snapshot and diff output for PostgreSQL and EnterpriseDB views could include an unexpected leading space and drop redundant parentheses around WHERE clauses, causing false view drift. View definitions now match byte-for-byte with prior output.
  • Changelog Generation and Snapshot(SECURE-488) Fixed diffChangeLog on PostgreSQL to correctly handle schemas that differ only by constraint or index names, generating a valid, convergent changelog instead of one that failed on update.
  • Changelog Generation and Snapshot(SECURE-90) Liquibase now accurately remediates detected trigger changes in PostgreSQL, so drift-detection deployments no longer fail when a trigger already exists in the target database.
  • Changelog Generation and Snapshot(SECURE-410) Fixed a bug where createIndex on MySQL generated a SQL syntax error when deploying functional indexes with computed="true" columns, due to missing double parentheses required by MySQL 8.0.13 and later.
  • Changelog Generation and Snapshot(SECURE-43) You can now generate and deploy changelogs from MySQL 8.0 databases with expression defaults like DEFAULT (CURRENT_DATE) without a SQL syntax error.
  • Changelog Generation and Snapshot(SECURE-214) Fixed an issue where deploying addForeignKeyConstraint with validate="false" against Db2 LUW created a fully enforced foreign key. Liquibase now appends the NOT ENFORCED clause, matching Oracle and PostgreSQL, so redeploying preserves the constraint state and no longer causes false drift.
  • Changelog Generation and Snapshot(SECURE-158) Updated the renameViewColumnsAndUpdateBody rollback error message to explain that oldBody is required for rollbacks. Previously the rollback failed with an unclear NullPointerException. This issue was present in Liquibase Secure 5.2.0.
  • Changelog Generation and Snapshot(SECURE-376) Fixed an inconsistency in validate --strict where an unquoted null changeset attribute value was flagged in XML, YAML, and formatted SQL changelogs but silently ignored in JSON.
  • Changelog Generation and Snapshot(INT-2281) generate-changelog now wraps a PostgreSQL generated column's expression in parentheses when needed, so you can replay changelogs for columns whose expression starts with a function call (such as make_date(...)) without hitting a syntax error. This issue has been present since PostgreSQL generated column support was added in 2023.
  • Changelog Generation and Snapshot(SECURE-689) Fixed an issue where EDB synonym names accumulated quote characters across repeated snapshot and generate-changelog cycles, until the DROP SYNONYM statement Liquibase generated no longer matched the object and drop-all failed. Liquibase now reads the synonym name from the EDB catalog as the identifier actually stored there, and preserves the case you specified when it writes CREATE SYNONYM and DROP SYNONYM. This issue was present in Liquibase Secure 5.2.2 and earlier releases.
  • Changelog Generation and Snapshot(SECURE-560) Fixed an issue where diff and diff-changelog did not detect a renamed primary key constraint on Oracle. Liquibase reported no primary key difference and flagged only the backing indexes, so the generated changelog failed to deploy with ORA-02429. Renamed primary keys are now detected on Oracle and on the other case-insensitive databases. This issue was present in Liquibase Secure 5.2.2 and earlier releases.
  • Changelog Generation and Snapshot(INT-2273) generate-changelog no longer reports Generated changelog written to <path> when it did not actually write anything. When your database contains only the Liquibase tracking tables, the command now prints the same "Changelog not generated" message you already see for a completely empty database, instead of claiming success while creating no file.
  • Changelog Generation and Snapshot(INT-2097) On Couchbase, snapshot, diff, diff-changelog, generate-changelog, and drop-all now report that the command is not supported instead of failing with an internal error. diff and generate-changelog also exit with a non-zero status when they fail, so a pipeline that gates on the exit code no longer treats the failure as a success.
  • Changelog Generation and Snapshot(INT-2228) PostgreSQL rollbacks now succeed when a renamed view's column count changed When you used diff-changelog to capture a view column rename that also changed the number of columns in the view, rolling back that change on PostgreSQL could fail with a "cannot drop columns from view" error. Rollback now recreates the view instead of trying to replace it in place when the original definition has fewer columns than the current one, so the rollback completes successfully and restores the original column name and view body. This issue was present in Liquibase Secure 5.2.0.
  • Changelog Generation and Snapshot(INT-2229) When diff-changelog generates a dropColumn for a column that a view still uses, it now puts the view update first, so the changelog deploys without you reordering changesets by hand. This issue was present in Liquibase Secure 5.2.0 and later.
  • Changelog Generation and Snapshot(INT-2251) When you snapshot, diff, or generate a changelog for a CockroachDB schema, Liquibase no longer reports descending-order indexes as unique constraints.
  • Changelog Generation and Snapshot(INT-2262) Liquibase now rejects a formatted SQL changeset whose boolean attribute has a value other than true or false. A changeset such as --changeset alice:1 runAlways:banana fails with ERROR [LB-CHG-0017], naming the attribute and the value, and the command exits 1. In Liquibase Secure 5.2.2 and earlier the value was silently treated as false and the command succeeded, so a changelog carrying a typo in a boolean attribute has been running without applying the flag you intended. Correct the value to true or false to deploy. This applies to formatted SQL changelogs. YAML and JSON changelogs still accept an invalid boolean and treat it as false, and XML has always rejected it.
  • Changelog Generation and Snapshot(SECURE-330) modifyChangeSets now supports the labels and contexts attributes, so you can apply them in bulk to the changesets in an included changelog. Attribute names are case-insensitive, and this works in every changelog format that supports modifyChangeSets.
  • Changelog Generation and Snapshot(SECURE-507) Fixed an issue where generate-changelog could silently drop a standalone index's createIndex statement on PostgreSQL and MySQL when the index shared columns with a UNIQUE constraint. This issue was present in Liquibase Secure 5.0, 5.1, and 5.2.
  • Changelog Generation and Snapshot(SECURE-515) When you run snapshot or generate-changelog against Microsoft SQL Server with --schemas, Liquibase no longer captures database-level DDL triggers that fall outside the schemas you selected, so the generated changelog no longer fails to deploy on an object that a trigger references outside your filter. This issue was present in Liquibase Secure 5.1.1 and the 5.2 line.
  • Changelog Generation and Snapshot(SECURE-532) generate-changelog now preserves index prefix lengths on MySQL and MariaDB, so a changelog generated from a schema with prefix indexes reproduces those indexes instead of dropping the length. Previously the generated changelog failed to deploy with a key-length error on TEXT and BLOB columns, and did not reproduce the source index on other column types. Unique prefix indexes are not covered and are still generated without the prefix length. This issue was present in Liquibase Secure 5.1.1 and 5.2.1.
  • Changelog Generation and Snapshot(SECURE-545) Generating a changelog or snapshot from a MySQL database no longer changes the type of your boolean and time columns. Before this fix, a TINYINT(1) column you use for a boolean value could come back as TINYINT(3), and a TIME column with fractional-second precision, like TIME(6), could lose that precision entirely, which meant redeploying from that changelog could truncate sub-second time values you already had. Both TINYINT(1) and TIME(N) now come through exactly as they appear in your database. This issue was present in Liquibase Secure 5.2.1.
  • Changelog Generation and Snapshot(SECURE-559) When a primary key constraint is renamed on Oracle, diff-changelog no longer generates a redundant createIndex for its backing index, so the changelog no longer fails with ORA-01408 when you run update. This matches the existing behavior on PostgreSQL.
  • Changelog Generation and Snapshot(SECURE-568) Liquibase now consistently rejects an unrecognized database type in your SQL changelog filename, including when you use --object-changelogs or connect to PostgreSQL, where the check could previously be skipped. This issue was present in Liquibase Secure 5.2.1.
  • Changelog Generation and Snapshot(SECURE-742) Fixed an issue where generate-changelog with --overwrite-output-file=true emptied an existing output file when the database had no changesets to write, so a changelog you already had became a zero-byte file while the command reported success. This issue is present in every released version up to and including Liquibase Secure 5.2.2.
  • Changelog Generation and Snapshot(INT-2295) generate-changelog and diff-changelog no longer fail with Unknown boolean value when a PostgreSQL table has a boolean generated column. Previously a single such column caused the command to abort without producing a changelog. This issue has been present since PostgreSQL generated column support was added.
  • Changelog Generation and Snapshot(SECURE-211) Fixed an issue where Liquibase could compute an incorrect checksum for a dbms-scoped <sqlFile> change (for example, <sqlFile dbms="mssql" .../>) when the checksum was calculated before the target database was known in scope, such as under liquibase flow. The affected changeset's checksum resolved to the hash of an empty string, which could cause runOnChange changesets to silently stop detecting further script edits, with no warning or error. Note: If a changeset was affected by this issue before upgrading, Liquibase automatically corrects the stored checksum the next time you run update. For runOnChange changesets, this correction happens by re-running the changeset one additional time. If the changeset's SQL is not idempotent (for example, a plain INSERT rather than MERGE or INSERT ... WHERE NOT EXISTS), this can insert one duplicate row. Idempotent SQL is unaffected.
  • Changelog Generation and Snapshot(SECURE-417) diff and diff-changelog now warn on the console, with the detail written to the log file, when --excludeObjects leaves behind objects that depend on something you excluded, such as a foreign key, a unique constraint, or the index backing it, so you find out before the generated changelog fails to deploy. This issue was present in Liquibase Secure 5.2.1 and earlier.
  • Changelog Generation and Snapshot(SECURE-550) generate-changelog no longer writes defaultValue="null" for a nullable MySQL or MariaDB ENUM column that has no default, so the generated changelog deploys instead of failing on MariaDB with Invalid default value. This issue was present in Liquibase Secure 5.2.1 and earlier.
  • Changelog Generation and Snapshot(SECURE-557) generate-changelog can now pretty-print the SQL it writes to SQL-format changelogs so long statements are readable and diff cleanly, which you turn on with liquibase.changelog.prettyPrintSql because it is off by default in this release.
  • Changelog Generation and Snapshot(SECURE-785) generate-changelog on SQL Server now quotes column default values, so a changelog it generates for a default such as ' ' or 'A' runs without a syntax error when you deploy it. This issue was present in Liquibase Secure 5.2.2.
  • Changelog Generation and Snapshot(SECURE-791) update-sql and other *-sql commands now keep a trailing comment at the end of a formatted-SQL changeset in the generated output when stripComments is false, instead of silently dropping it.
  • Changelog Generation and Snapshot(INT-2341) generate-changelog and diff-changelog no longer capture the system-managed io.unitycatalog.tableId table property on Databricks Unity Catalog. Databricks rejects that property when a user sets it, so a generated changelog containing it could not be deployed.
  • Database Support(INT-2053) Liquibase now supports PostgreSQL 18 VIRTUAL generated columns end to end. You can model VIRTUAL columns in your changelogs and deploy them, and snapshot, generate-changelog, and diff now preserve whether a generated column is VIRTUAL or STORED. Previously, round-tripping a PostgreSQL 18 schema silently re-shaped VIRTUAL columns as STORED.
  • Database Support(INT-1550) You can now use the set-labels and set-contexts commands with Formatted Mongo changelogs, so you can manage labels and contexts on MongoDB the same way you do with Formatted SQL changelogs.
  • Database Support(INT-2038) createDynamoTable now validates attributeDefinitions and tags up front in YAML and JSON changelogs, rejecting malformed structure before it reaches AWS instead of silently dropping tags. nonKeyAttributes projections now use a wrapped nonKeyAttribute syntax, fixing a bug where multiple entries collapsed to just the last one.
  • Database Support(INT-1961) Fixed an issue where dropAll failed with a NamespaceNotFound error on MongoDB 6 when the database contained views. MongoDB 7 and later were not affected.
  • Database Support(INT-2032) Fixed an issue where update could fail on BigQuery while creating the DATABASECHANGELOGLOCK table. BigQuery applies DDL with eventual consistency, so on large projects the table was not yet visible to the query engine when Liquibase checked it, and the run failed after several minutes of retries. Liquibase now waits for the new table to become queryable before continuing.
  • Database Support(INT-2098) You can now run consecutive changesets that create or delete a global secondary index on the same DynamoDB table, because Liquibase's waiter now waits for the index operation itself to finish instead of returning as soon as the table is active.
  • Database Support(INT-2263) On Couchbase, Liquibase now creates a secondary index on meta().id for the tracking collections, named liquibase_DATABASECHANGELOG_idx and liquibase_CHANGELOGLOCKS_idx, and no longer creates a primary index. An existing primary index is left in place, so an upgraded deployment keeps using it until you drop it once. After that Liquibase does not recreate it. Two consequences are worth planning for. Custom queries, scripts, and dashboards that read these collections should filter on the index key, for example WHERE meta().id IS NOT MISSING, because a query with no WHERE clause is no longer served by any index. On Couchbase 7.2 and earlier such a query fails, and on 7.6 and later it falls back to a sequential scan. And running an older version of Liquibase against the same database recreates a primary index on both collections, which Liquibase 6.0 then leaves in place, so a single run of an older version restores the primary index without reporting it.
  • Database Support(SECURE-664) Liquibase now preserves the case of your BigQuery project ID. In Liquibase Secure 5.2.0 through 5.2.2, Liquibase lowercased the project ID when it recorded the connection, so a connection to ProjectId=MyProject was recorded as myproject. If you have tooling that reads the recorded connection and treats the project ID as case-sensitive, it sees the correct value again after you upgrade.
  • Database Support(INT-2293) On Couchbase, a change that removes documents by ID no longer modifies the set of IDs you supplied, so the same change is safe to run again and passing an immutable set of IDs no longer fails with a confusing transaction error.
  • Database Support(SECURE-724) Liquibase Secure now bundles Oracle's ojdbc17 JDBC driver in place of ojdbc8, which Oracle recommends for Java 17 and later and which implements the standard JDBC 4.3 interfaces rather than Oracle's own extension classes.
  • Database Support(INT-2346) snapshot, generate-changelog, and drop-all no longer fail on Cassandra with a SQLRecoverableException about a closed result set. Foreign-key metadata, which Cassandra has none of, is no longer requested from the driver.
  • Database Support(INT-2031) Fixed an issue where deploying to AWS Keyspaces repeatedly dropped and recreated the DATABASECHANGELOGLOCK table during update and rollback, making deployments take significantly longer than they should.
  • Logging and Reports(SECURE-40) Fixed an issue where the Liquibase Maven plugin did not apply --log-level or --log-format unless the license key was set as an environment variable. All configuration methods (pom.xml, JVM system properties, environment variables, and the properties file) now apply structured logging correctly.
  • Logging and Reports(SECURE-486) Fixed the Maven plugin to recognize unprefixed logFormat, logLevel, logFile, and license key settings in a liquibase.properties defaults file, so structured logging and license detection work the same way they do via CLI arguments, pom configuration, and environment variables.
  • Logging and Reports(SECURE-52) Liquibase now correctly applies the log level you set in a Flow file's globalVariables section to all per-action log files, so you get the expected detail without repeating the setting in each action.
  • Logging and Reports(SECURE-50) Liquibase now writes validate command output to the --output-file you specify, so validation results and errors are available for CI/CD pipelines and other automated workflows.
  • Logging and Reports(SECURE-66) The embedded Python runtime moves from 3.11 to 3.12 (GraalPy 25.0.2). If you point liquibase.script.python.executablePath at your own virtual environment, recreate it against Python 3.12 before running policy checks, or they will fail with ModuleNotFoundError. If you use only the built-in checks or the embedded virtual filesystem, no action is needed.
  • Logging and Reports(SECURE-649) Liquibase Secure no longer strips comments from your SQL by default. Comments in formatted SQL changesets, sql and sqlFile changes, and stored procedure bodies now reach the database as written, where in Liquibase Secure 5.2.2 and earlier they were removed unless you opted out. Community Liquibase is unchanged and still strips comments by default. To restore the previous behavior everywhere, set global-strip-comments to true, or set stripComments on an individual changeset.
  • Logging and Reports(SECURE-459) Structured JSON logs now carry an errorClassification field alongside the existing liquibaseErrorCode, so you can tell a business failure from a system failure without parsing message text. Both values are stable and locale-independent, which makes them safe to match on in CI pipelines and alerting rules.
  • Logging and Reports(INT-2249) Liquibase 6.0 removes three Db2 for z/OS properties: liquibase.db2z.trackingTables.location.tablespace, liquibase.db2z.databasechangelog.index, and liquibase.db2z.databasechangeloglock.index. If you set any of them, remove them from your configuration. Db2 for z/OS now creates the tracking tables' tablespace and their primary-key index itself, and you can still name the database with liquibase.db2z.trackingTables.location.database. A removed property left in a defaults file is ignored, but it is rejected as a CLI flag and fails at startup under strict=true.
  • Logging and Reports(NTT-1333) The license tracking utility that shipped inside Liquibase Secure is no longer included as of Secure 6.0.
  • Logging and Reports(SECURE-463) If you embed Liquibase Secure in your own application (for example, Spring Boot), running a Liquibase command no longer changes your application's own logging levels or handlers, because Liquibase Secure's logging now runs through SLF4J instead of configuring Java's built in logging directly.
  • Logging and Reports(SECURE-536) Liquibase now always prints all four UPDATE SUMMARY lines, including Failed deployment: 0, when you rerun update against a changelog where every change set is already deployed. This issue was present in every Liquibase Secure 5.x release, and in 4.x releases back to at least 4.25.0.
  • Logging and Reports(SECURE-616) Liquibase 6.0 defines an exit-code contract for the Liquibase CLI. Exit code 0 still means success, and the exit code for a failure now depends on how that failure is classified rather than always being 1. If your scripts or CI/CD pipelines check the exit code, treat any nonzero value as a failure rather than testing for code 1 specifically. If your pipeline branches on exit code 1 to mean "any Liquibase failure", update it to fail on any nonzero code. This applies to the Liquibase CLI. The Maven and Spring integrations fail by throwing and do not consult the exit map.
  • Logging and Reports(SECURE-668) When a database connection fails, Liquibase no longer prints your password in the error message. If your JDBC URL carries credentials in the authority form (jdbc:postgresql://user:password@host:port/database), a failed connection used to echo the driver's error text as it was, so your username and password appeared in cleartext on the console, in your --log-file (both text and JSON output), and in Maven plugin output, for both url and referenceUrl. Liquibase now removes credentials from exception messages before they reach any of those places. Passwords you supply with --password, with an environment variable, or as query parameters in the URL (?user=&password=) were never affected. If you have used the authority form, check any log files you have kept and rotate the credentials that appeared in them. This issue was present in Liquibase Secure 5.2.1.
  • Logging and Reports(SECURE-677) You can now use lowercase log-level values (for example fine) in a flow file's globalArgs, matching the behavior of the --log-level CLI flag and the liquibase.logLevel properties file setting. An unrecognized value now falls back to INFO with a warning instead of stopping the flow with a raw exception.
  • Logging and Reports(SECURE-695) Fixed an issue where rollback-one-changeset and rollback-one-update printed the same failure warning twice, once in the console output and once in the generated HTML report, when the targeted changeset could not be located. This issue was present in Liquibase Secure 5.2.2.
  • Logging and Reports(SECURE-713) Fixed an issue where the Maven plugin's dbcl-history and flow goals left their output file open after the goal finished, which could exhaust file handles during a long Maven build that invokes them repeatedly. This issue was present in Liquibase Secure 5.2.0, 5.2.1, and 5.2.2.
  • Logging and Reports(SECURE-732) Fixed an issue where the last line written to a log file or output file on Azure Blob Storage was silently missing. When --log-file or --output-file targeted an az:// location, the blob was created and correctly populated except for its final line, usually the command-completion message, and no error or warning appeared anywhere. The full content is now written, and a failure to write reports an error instead of being discarded.
  • Logging and Reports(SECURE-460) As of Liquibase 6.0, the CLI writes command results (SQL, JSON, diff output, and the text results of look-up commands) to STDOUT, and everything else, including the banner, progress messages, success confirmations, warnings, and errors, goes to STDERR. You're affected if your scripts or CI pipeline capture STDOUT from update, rollback, or dbDoc, since those commands have no machine-readable result and now write everything to STDERR instead. The look-up commands status, history, and checks run keep their results on STDOUT. You're not affected if you only capture the structured output of commands like update-sql, snapshot, or diff (that was already on STDOUT), or if you don't parse Liquibase's output streams at all. If you need time to update your scripts, set liquibase.legacyStreamRouting (or the LIQUIBASE_LEGACY_STREAM_ROUTING environment variable, or the --legacy-stream-routing flag) to restore the combined pre-6.0 stream behavior. This compatibility option is deprecated and will be removed in Liquibase 6.2.
  • Logging and Reports(SECURE-462) Command output is now cleaner and keeps your credentials out of view. Benign command failures no longer print a full stack trace by default. You'll only see one when you run with --log-level=FINE. You can also see how many rows each statement affected without turning on full SQL logging. Set the new --show-rows-affected=true flag and commands like update print a line such as "3 row(s) affected" after each insert, update, or delete. The flag is off by default, so your existing output is unchanged unless you opt in, and it works independently of --sql-log-level. If you use the Maven plugin with verbose output (-e or -X), your database credentials no longer appear in the JDBC URLs it prints.
  • Logging and Reports(SECURE-461) You can now control how much detail Liquibase prints during a command with the new --verbosity flag (quiet, normal, or verbose), plus a --quiet shortcut. Choose quiet to strip the banner, license line, changeset headers, and other narration from your output, without losing the results themselves. For example, update-sql --quiet still prints the SQL. Choose verbose to add fine-grained diagnostic detail, including stack traces, when you're troubleshooting. The normal tier, which is the default, looks and behaves exactly like today's output, so upgrading doesn't change what you see unless you ask it to. If you already set --log-level explicitly, that choice still wins over whatever verbosity implies.
  • Logging and Reports(INT-2268) When update, update-to-tag, or update-one-changeset fails with an error Liquibase does not recognize, such as an error raised by a database driver, you now see the original error instead of a ClassCastException, and rollbackOnError runs as expected.
  • Logging and Reports(SECURE-289) status --verbose now takes an optional comma-separated list of the changeset attributes you want to see, such as status --verbose=labels,teams,runwith,runonchange, and a new status --simple flag suppresses the per-changeset line so you see only the count of pending changesets.
  • Logging and Reports(SECURE-596) drop-all now fails with a clear error when you point it at an offline database URL, instead of permanently deleting the file named in that URL's changeLogFile parameter. This issue was present in Liquibase Secure 5.2.1 and earlier.
  • Logging and Reports(SECURE-792) Setting the LIQUIBASE_LOG_LEVEL environment variable now lowers the Maven console log level, so LIQUIBASE_LOG_LEVEL=ERROR keeps INFO lines out of your Maven build output.
  • Logging and Reports(SECURE-885) JDBC driver warnings, such as SQL Server's "Changed database context" message on every USE statement, go to the log again instead of the console, so log-level controls whether you see them. Since Liquibase Secure 5.0.0 they printed on every run whatever your log level, and printed a second time as a mirrored log line whenever a log level was set. This issue was present in Liquibase Secure 5.0-5.2.
  • Logging and Reports(SECURE-793) A defaults-file key scoped to another command, such as liquibase.command.checks.run.autoUpdate, no longer produces a Potentially ignored key(s) warning when you run a different command, and no longer fails the run at startup when you also set strict=true. This issue was present in Liquibase Secure 5.2.2 and earlier.
  • Logging and Reports(SECURE-741) On Windows running Liquibase Secure under Java 17, the --log-file was written using the JVM's default platform charset (Cp1252) while console output was correctly encoded as UTF-8. Non-ASCII changeset authors, remarks, and other changelog text that displayed correctly on the console was corrupted in the log file. In a plaintext log, any character outside Cp1252, including CJK and Cyrillic text, was replaced with ? and cannot be recovered. In a JSON log (--log-format=JSON), the same text was double-encoded into mojibake that most log consumers cannot repair. Java 18 and later were not affected. Liquibase now pins the log file encoder to UTF-8 independently of the JVM's default charset, matching the console. If you ran Liquibase Secure on Windows with Java 17 and kept log files containing non-ASCII changeset authors or remarks, check them for corruption. Any plaintext log showing ? in place of that text has lost the original characters permanently.
  • Logging and Reports(SECURE-750) When you ran an update with --show-summary-output=LOG and did not also set --output-file, the UPDATE SUMMARY was printed to STDOUT in addition to the log file, even though STDOUT was not the requested destination. This could interfere with scripts or tooling that parse STDOUT output. Liquibase now writes the summary only to the log file in this case, leaving STDOUT clean. The summary still reaches --output-file when you set one, and --show-summary-output=CONSOLE and ALL are unaffected.
  • Logging and Reports(SECURE-752) When Liquibase could not open the file given to --log-file and fell back to console logging, the warning message included that file path exactly as supplied. If the path contained a carriage return or line feed character, it could inject additional, fabricated lines into the log output. Liquibase now strips carriage returns and line feeds from the --log-file path before including it in this fallback warning message.
  • Logging and Reports(SECURE-824, SECURE-836) With rollback-on-error set, Liquibase now runs a failed changeset's own <rollback> only when that changeset could have committed part of its work before failing, which covers runWith, runInTransaction="false", and Oracle, where every DDL statement commits on its own. A failure inside an intact transaction leaves the database as it was, so Liquibase reports that no deployed changesets were found to roll back instead of running a rollback against objects that were never created and warning that manual intervention is required. This issue was present in Liquibase Secure 5.2.1 and 5.2.2.
  • Logging and Reports(SECURE-803) A failing validate now writes its list of validation errors to STDOUT as the command's result, with ERROR [LB-CHG-0035] Changelog validation failed and a non-zero exit code on STDERR. In Liquibase Secure 5.0-5.2 the error list went to STDERR only, so a script capturing STDOUT got nothing.
  • Logging and Reports(SECURE-887) The totalSkipped value in structured logs now includes changesets skipped because of preconditions, an operating system mismatch, or licensing, so it agrees with the individual skip counts reported beside it. The update summary detail table also reaches --output-file when --show-summary-output is LOG, as it already did for CONSOLE. Automation that reads totalSkipped will see higher numbers than before.
  • Logging and Reports(SECURE-888) Changesets that failed to deploy are no longer counted as skipped in the structured log's update summary. Automation that reads the skipped counts will see lower numbers than before, because entries for failed and exception-skipped changesets are no longer included.