Chapter 1. Migrating applications to Red Hat build of Quarkus 3.20


As an application developer, you can migrate applications that are based on Red Hat build of Quarkus version 3.2 or later to version 3.20 by using either the quarkus CLI or Maven.

Important

The Quarkus CLI is intended for development purposes, including tasks such as creating, updating, and building Quarkus projects. However, Red Hat does not support using the Quarkus CLI in production environments.

1.1. Updating projects to the latest Red Hat build of Quarkus version

To update your Red Hat build of Quarkus projects to the latest version, follow these steps, which are explained in detail later in this guide:

  1. Use the quarkus CLI or Maven commands to run automated update tasks.
  2. Consult the Changes that affect compatibility with earlier versions section to perform any manual update tasks.

1.1.1. Automatic updates

Running the quarkus CLI or Maven commands triggers OpenRewrite recipes that upgrade project dependencies and source code. This automated approach provides a convenient and reliable way to update your projects.

However, not all migration tasks are automated. If specific updates are not applied after running the quarkus update command or its Maven equivalent, consider the following possible reasons:

  • The required migration task is not covered by the available OpenRewrite recipes.
  • An extension your project depends on is incompatible with the latest Red Hat build of Quarkus version.

1.1.2. Manual updates

Manual updates give you the flexibility and control to address any migration tasks to ensure your project aligns with your specific needs. Tasks that are not automated must be handled manually.

For a list of the migration tasks required to update from the previous release to this one, see the Changes That Affect Compatibility with Earlier Versions section of this guide.

Reviewing the migration guide for each release version between the current version of your application project and the version you’re upgrading to is essential. This review process ensures you are fully informed and prepared for the update process. For example, if upgrading from version 3.15 to 3.20, you only need to review this guide. If you are upgrading from version 3.2 to 3.20, you must also review the guides for for each intermediate version:

Each task in this migration guide outlines the required changes and indicates whether they are automatically handled by the quarkus update command and its Maven equivalent.

For additional background, see the Quarkus community Migration guides.

1.2. Using the quarkus CLI to update the project

Update your Red Hat build of Quarkus projects by using the quarkus CLI.

Important

The Quarkus CLI is intended for development purposes, including tasks such as creating, updating, and building Quarkus projects. However, Red Hat does not support using the Quarkus CLI in production environments.

Prerequisites

Procedure

  1. Create a working branch for your project in your version control system.
  2. Install the latest version of the quarkus CLI by following the installation guide.
  3. Verify the installation by running the following command:

    quarkus -v
    3.20.0
  4. Important: Configure the extension registry client as instructed in the Configuring Red Hat build of Quarkus extension registry client section of the "Getting Started with Red Hat build of Quarkus" guide.
  5. In the terminal, navigate to your project directory.
  6. Update the project:

    quarkus update

    Optional: To update to a specific stream, use the --stream option followed by a specific version; for example:

    quarkus update --stream=3.20
  7. Review the output from the update command for instructions and perform any suggested tasks.
  8. Use a diff tool to inspect all changes made during the update process.
  9. Manually perform any changes that were not handled by updating the project. For details, refer to the following Changes that affect compatibility with earlier versions section.
  10. Ensure the project builds without errors, all tests pass, and the application functions as expected before deploying to production.

1.3. Using Maven to update the project

Update your Red Hat build of Quarkus projects by using Maven.

Prerequisites

Procedure

  1. Create a working branch for your project in your version control system.
  2. Important: Configure the extension registry client as detailed in the Configuring Red Hat build of Quarkus extension registry client section of the "Getting Started with Red Hat build of Quarkus" guide.
  3. Open a terminal and navigate to your project directory.
  4. Ensure that the Red Hat build of Quarkus Maven plugin version is aligned with the latest supported version. Configure the project according to the Getting started with Red Hat build of Quarkus guide, and then run:

    mvn com.redhat.quarkus.platform:quarkus-maven-plugin:3.20.0.redhat-00002:update

    Optional: To update to a specific stream, use the -Dstream option followed by the desired version; for example:

    mvn com.redhat.quarkus.platform:quarkus-maven-plugin:3.20.0.redhat-00002:update -Dstream=3.20
  5. Review the output from the update command for any instructions and perform the suggested tasks.
  6. Use a diff tool to examine all changes made during the update process.
  7. Manually perform any changes that were not handled by updating the project. For details, refer to the following Changes that affect compatibility with earlier versions section.
  8. Ensure the project builds without errors, all tests pass, and the application functions as expected before deploying to production.

1.4. Changes that affect compatibility with earlier versions

This section describes changes in Red Hat build of Quarkus 3.20 that affect the compatibility of applications built with earlier product versions.

Review these breaking changes and take the necessary steps to ensure that your applications continue functioning after updating them to Red Hat build of Quarkus 3.20.

You can perform many of the updates listed in this section by running quarkus update or the equivalent Maven command. This triggers automated OpenRewrite recipes that update your project dependencies and source code to the latest Red Hat build of Quarkus version.

However, not all migration tasks are automated. If specific updates aren’t applied by the automated update, it might be because the required migration task isn’t covered by the available OpenRewrite recipes or an extension your project relies on is incompatible with the latest version. In such cases, you need to perform the updates manually. Be sure to review the following items to identify and address any manual migration tasks.

1.4.1. Cloud

1.4.1.1. OpenShift and Kubernetes: Fabric8 Kubernetes Client upgraded to version 7.1

In Red Hat build of Quarkus 3.20, the following extensions upgrade the Fabric8 Kubernetes Client from version 6.13 to 7.1.

  • quarkus-openshift
  • quarkus-openshift-client
  • quarkus-kubernetes
  • quarkus-kubernetes-client

Breaking changes

The upgraded Fabric8 Kubernetes Client includes breaking changes affecting the quarkus-kubernetes-client and quarkus-openshift-client extensions.

Although the quarkus-openshift and quarkus-kubernetes extensions use Fabric8, their functionality remains unchanged, so you do not need to make any updates for them.

The io.quarkus:quarkus-test-openshift-client module has been removed as part of this upgrade. If your tests use this module, migrate to io.quarkus:quarkus-test-kubernetes-client, which offers equivalent functionality. For more information, see the OpenShift client section of the Quarkus "Kubernetes Client" guide.

The upgraded Fabric8 Kubernetes Client reorganized some model types and classes, moving some to different modules. To find their new locations, refer to the official Fabric8 Kubernetes Client: Migration from 6.x to 7.x guide.

Review your application for any affected dependencies, configurations, or API usages, and update them as needed. Then, thoroughly test your application to ensure full compatibility with Fabric8 7.1.

Note

Red Hat build of Quarkus 3.20 provides Developer Preview support for the quarkus-kubernetes extension, and does not currently support the quarkus-kubernetes-client extension. However, if you use these extensions, the described change might affect your migration.

This change requires manual intervention. It is not included in the automated update process described in the Migrating applications to Red Hat build of Quarkus 3.20 guide.

1.4.2. Compatibility

1.4.2.1. Removal of Reactive rename compatibility layer

In Red Hat build of Quarkus 3.15, many extensions and configuration properties were renamed as part of the rebranding of RESTEasy Reactive to Quarkus REST and Reactive Messaging to Quarkus Messaging. To support this transition, artifact relocations and configuration fallbacks were introduced.

In Red Hat build of Quarkus 3.20, these artifact relocations and configuration fallbacks have been removed. You must now use the new artifact names and configuration properties.

For more additional background information, see the RESTEasy Reactive extensions renamed to Quarkus REST section of the "Release Notes for Red Hat build of Quarkus 3.15" guide.

1.4.3. Core

1.4.3.1. Default locale configuration enhanced

Red Hat build of Quarkus 3.20 updates locale handling to align with Mandrel version 24.2 and later.

Breaking changes

In earlier releases, applications inherited the default locale from the build system.

To ensure consistent locale behavior across all applications, Red Hat build of Quarkus applies a standardized default locale strategy. Use the following table to determine how your application’s behavior changes based on your locale configuration.

Application propertiesLocales included in native executableDefault locale at run time

Neither quarkus.locales nor quarkus.default-locale is set

en_US

en_US

Only quarkus.locales is set

Locales listed in quarkus.locales and en_US

en_US

Only quarkus.default-locale is set

en_US

Value of quarkus.default-locale

Both quarkus.locales and quarkus.default-locale are set

Locales listed in quarkus.locales and en_US

Value of quarkus.default-locale

The en_US locale is always embedded in the native executable, regardless of the quarkus.locales configuration.

Note

If you set quarkus.default-locale, Red Hat build of Quarkus sets the user.language and user.country system properties at run time. For JDK 24 and later with GraalVM or Mandrel, you can also override these properties directly.

Review your application’s locale settings in the configuration properties and, if necessary, update the settings to avoid unexpected changes in behavior.

This change requires manual intervention. It is not included in the automated update process described in the Migrating applications to Red Hat build of Quarkus 3.20 guide.

1.4.3.2. SmallRye Fault Tolerance: Fallback and BeforeRetry methods now defined at build time

In Red Hat build of Quarkus 3.20, the configuration properties for @Fallback.fallbackMethod() and @BeforeRetry.methodName() are now resolved at build time and cannot be changed at runtime. The affected configuration properties are:

  • <class_name>/<method_name>/Fallback/fallbackMethod
  • <class_name>/Fallback/fallbackMethod
  • Fallback/fallbackMethod
  • <class_name>/<method_name>/BeforeRetry/methodName
  • <class_name>/BeforeRetry/methodName
  • BeforeRetry/methodName

This change ensures proper reflection configuration and compatibility with native image compilation.

1.4.3.3. SmallRye Fault Tolerance version 6.7.0 deprecates first-generation programmatic API

In Red Hat build of Quarkus 3.20, the quarkus-smallrye-fault-tolerance extension includes SmallRye Fault Tolerance 6.7.0, which introduces no breaking changes but includes the following updates:

  • The first version of the programmatic API (FaultTolerance, @ApplyFaultTolerance) is deprecated and planned for removal in SmallRye Fault Tolerance 7.0. The second version (Guard, TypedGuard, @ApplyGuard) serves as a replacement, but there are notable differences.
  • Specification-defined configuration properties remain available, but Red Hat build of Quarkus now provides native configuration properties you can use instead.

For more information, see the SmallRye Fault Tolerance 6.7.0 release announcement, which includes links to the migration guides for the programmatic API and details about the new configuration properties. The Quarkus SmallRye Fault Tolerance guide provides a complete reference for these configuration properties.

1.4.3.4. Scheduler methods now require a started scheduler

Starting in Red Hat build of Quarkus 3.20, the behavior of methods in io.quarkus.scheduler.Scheduler has changed.

When the scheduler is not started, almost all methods now throw an UnsupportedOperationException.

To verify whether the scheduler is running, you can use a new method, Scheduler#isStarted().

This change affects scheduler instances coming from both the quarkus-scheduler and quarkus-quartz extensions.

1.4.3.5. Management interface now listens on localhost in development and test modes

Starting in Red Hat build of Quarkus 3.20, when you use development and test modes, the management interface listens on the localhost interface by default instead of on 0.0.0.0. This change aligns with the behavior of the main interface.

On Windows with Windows Subsystem for Linux (WSL), both the management and main interfaces continue to listen on 0.0.0.0.

For more information, see the Quarkus Management interface reference guide.

1.4.3.6. Migration to @ConfigMapping and deprecation of configuration classes

In Red Hat build of Quarkus 3.20, configuration has migrated to the @ConfigMapping framework. This change deprecates the legacy configuration classes in favor of a unified configuration model based on interfaces and method signatures.

A compatibility layer remains in place for certain commonly used configuration classes, but it is planned for removal in a future release.

1.4.3.7. Builder and runtime base images upgraded to UBI 9

Starting in Red Hat build of Quarkus 3.20, Red Hat builder and runtime base images are upgraded to use Red Hat Universal Base Image 9 (UBI 9).

When upgrading from UBI 8 to UBI 9, be aware that changes in system dependencies, native image builds, or package and GNU C Library (glibc) version updates might affect your application’s behavior or runtime environment. Review and update your configurations as needed.

If you encounter issues with UBI 9, you can manually switch back to using UBI 8:

Table 1.1. Switching back to UBI 8
ImagesActions

Builder images

Set the builder image manually as follows:

  • -Dquarkus.native.container-build=true
  • registry.access.redhat.com/quarkus/mandrel-for-jdk-21-rhel8:23.1

Runtime images

Depending on the mode, apply the following settings:

  • JVM mode:

    • In your Dockerfile in the src/main/docker/ directory, specify registry.access.redhat.com/ubi8/openjdk-21 as the base image of your container.
  • Native mode:

    • To use UBI minimal, specify registry.access.redhat.com/ubi8/ubi-minimal:8.10.

For more information, see the following resources:

1.4.4. Data

1.4.4.1. Datasource: Removal of implicit default URL for reactive SQL datasources

In earlier versions of Red Hat build of Quarkus, when Dev Services were disabled or running in production mode, the quarkus.datasource.reactive.url and quarkus.datasource.<datasource-name>.reactive.url properties were implicitly set to an undocumented default, targeting localhost with a database-specific port.

Starting in Red Hat build of Quarkus 3.20, these properties no longer have a default value when Dev Services are disabled or the application is running in production mode. If the property is not set, the corresponding datasource is deactivated. If the application attempts to use a deactivated datasource, it will fail at startup. For details, see the Datasource usage fails fast if datasource is deactivated or has no URL set release note.

If your application requires an active datasource and you want it to connect to a database on localhost, you must now set the quarkus.datasource.reactive.url or quarkus.datasource.<datasource-name>.reactive.url property explicitly. For example:

quarkus.datasource.reactive.url=postgresql://localhost:5432/mydatabase

In earlier versions, this configuration was set implicitly. Starting with this release, you must define the URL to activate the datasource.

1.4.4.2. Datasources without a URL no longer contribute to a health check

Previously, when Dev Services were disabled or in production mode, Red Hat build of Quarkus contributed a health check for datasources even if quarkus.datasource.jdbc.url, quarkus.datasource.<datasource-name>.jdbc.url, quarkus.datasource.reactive.url, or quarkus.datasource.<datasource-name>.reactive.url properties were not set. This caused unreliable health checks that always succeeded for JDBC datasources and almost always failed for reactive datasources.

Starting with Red Hat build of Quarkus 3.20, datasources without a URL no longer contribute a health check. To ensure a health check is available, explicitly set the quarkus.datasource.jdbc.url, quarkus.datasource.<datasource-name>.jdbc.url, quarkus.datasource.reactive.url, or quarkus.datasource.<datasource-name>.reactive.url property.

1.4.4.3. Datasource usage fails fast if datasource is deactivated or has no URL set

In Red Hat build of Quarkus 3.20, applications start successfully even if a datasource is deactivated with quarkus.datasource.active=false or lacks a URL. This behavior often leads to runtime failures when the datasource is first accessed, especially when Dev Services are disabled or in production mode.

With this update, applications fail to start if Red Hat build of Quarkus detects that a datasource is used but is either deactivated or missing a URL.

Red Hat build of Quarkus now enforces stricter validation during startup to catch these issues early:

  • Static CDI Injection: If a datasource is injected statically using @Inject DataSource or @Inject Pool, the application will fail to start with a clear and actionable error message.
  • Dynamic Retrieval: Datasources retrieved dynamically, such as by using Arc.container().instance() or @Inject Instance<DataSource>, will not be detected during startup. However, retrieving these beans at runtime will throw an explicit exception with actionable guidance.

The same validation applies to the Flyway and Liquibase extensions for their Flyway and LiquibaseFactory CDI beans.

Note

Red Hat build of Quarkus 3.20 does not currently support the Flyway and Liquibase extensions. However, if you use these extensions, the described change might affect your migration.

Impact on Applications

  • If your application uses a datasource, Flyway, or LiquibaseFactory bean that may be deactivated or lack a URL, you could encounter a startup failure like the following:

    io.quarkus.arc.InactiveBeanException: Bean is not active: SYNTHETIC bean [class=io.agroal.api.AgroalDataSource, id=sqqLi56D50iCdXmOjyjPSAxbLu0]
    Reason: Datasource' <default>' was deactivated automatically because its URL was not set.
  • To activate the datasource, set configuration property quarkus.datasource.jdbc.url.

    For more information, see the Configure data sources guide.

How to resolve if the datasource should be active

Ensure that all required configuration properties are set:

  1. Set quarkus.datasource.jdbc.url or the appropriate configuration for the datasource type to ensure it is properly activated.

How to resolve if the datasource might be inactive

Adjust your code or configuration to handle inactive datasources gracefully:

  1. Deactivate unused extensions: If an extension depends on a datasource that might not be active, deactivate the extension explicitly by setting its active configuration property to false. For example:

    • quarkus.hibernate-search-standalone.active=false
    • quarkus.hibernate-search-orm.active=false
    • quarkus.hibernate-orm.active=false
    • quarkus.flyway.active=false
    • quarkus.datasource.active=false
  2. Inject dynamically: Instead of using static CDI injection, use @Inject InjectableInstance<DataSource> to check if the datasource bean is active before using it.

    if (ds.getHandle().getBean().isActive()) {
    DataSource dataSource = ds.get();
    // Use the datasource
    }

    These changes improve application reliability by detecting misconfigured datasources early, preventing unexpected runtime errors.

1.4.4.4. Flyway version 11 removes cleanOnValidationError

In Red Hat build of Quarkus 3.20, the quarkus-flyway extension upgrades Flyway to version 11, which removes the cleanOnValidationError configuration parameter. Additionally, calling Flyway.validate() no longer cleans on validation error.

To mitigate this change, Red Hat build of Quarkus 3.20 introduces the quarkus.flyway.validate-at-start.clean-on-validation-error configuration property, which provides behavior similar to cleanOnValidationError, but applies only when the application starts.

Workaround: If you require the previous behavior of cleanOnValidationError in explicit calls to Flyway.validate(), consider catching validation errors in your application and triggering a database cleanup explicitly using Flyway.clean().

Note

Red Hat build of Quarkus 3.20 does not currently support the Flyway extension. However, if you use this extension, the described change might affect your migration.

This change requires manual intervention. It is not included in the automated update process described in the Migrating applications to Red Hat build of Quarkus 3.20 guide.

For more information, see the Quarkus Using Flyway guide.

1.4.4.5. IBM Db2 driver and container image upgraded to version 12

In Red Hat build of Quarkus 3.20, the IBM Db2 driver and container image that Dev Services uses have been upgraded to version 12.

The automated update described in the Migrating applications to Red Hat build of Quarkus 3.20 guide upgrades the IBM Db2 driver and container image to version 12.

Breaking changes

This upgrade introduces breaking changes to the license registration process and connectivity configuration.

Review the new license requirements, configuration steps, and SSL/TLS settings detailed on IBM’s Features with behavior changes when upgrading to the Db2 Connect 12.1 driver for upgrading to Db2 Connect 12.1.

This change requires manual intervention. It is not included in the automated update process described in the Migrating applications to Red Hat build of Quarkus 3.20 guide.

1.4.4.6. Hibernate ORM Bean Validation contributes to DDL by default

In Red Hat build of Quarkus 3.20, the default behavior of Hibernate ORM’s Bean Validation integration has changed. Previously, validation constraints were not considered during Data Definition Language (DDL) generation. With this release, Hibernate ORM includes applicable validation constraints in DDL by default, ensuring that database schemas align more closely with application-level constraints.

  • To revert to the previous behavior where validation constraints do not influence DDL generation, set the quarkus.hibernate-orm.validation.mode configuration property to callback:

    quarkus.hibernate-orm.validation.mode=callback

The quarkus.hibernate-orm.validation.enabled property has also been deprecated.

  • To disable Bean Validation integration, use the following setting:

    quarkus.hibernate-orm.validation.mode=none

For more information about these changes and guidance on migrating your application, see the Migration Guide 3.19, or the following resources:

1.4.5. Logging

1.4.5.1. quarkus.log.*.json property deprecated

In Red Hat build of Quarkus 3.20, the quarkus.log.*.json configuration property has been deprecated. To enable JSON formatting for logging, use the quarkus.log.*.json.enabled property instead.

  • Update your configuration as follows:

    quarkus.log.console.json.enabled=true

This change was introduced to improve compatibility with YAML configuration, where the previous structure required using special syntax such as ~ to assign a value to the root key, leading to confusing or error-prone setups.

For more information, see the Migration Guide 3.19.

1.4.6. Observability

1.4.6.1. OpenTelemetry: Database incubating values moved

In Red Hat build of Quarkus 3.20, the quarkus-opentelemetry extension introduces breaking changes because some database incubating values, such as those related to Redis, were moved to a different package.

OpenTelemetry does not maintain a list of changes for database semantic conventions because they are not yet stable.

This change might require manual intervention, if you use manual instrumentation. It is not included in the automated update process described in the Migrating applications to Red Hat build of Quarkus 3.20 guide.

1.4.6.2. SmallRye OpenTracing: Extension and related JDBC tracing configuration removed

In Red Hat build of Quarkus 3.20, the previously deprecated quarkus-smallrye-opentracing extension and related configuration property quarkus.datasource.jdbc.tracing have been removed.

The quarkus-opentelemetry extension is now the preferred tracing solution. To enable JDBC tracing with OpenTelemetry, use the following configuration property:

quarkus.datasource.jdbc.telemetry=true

To migrate, replace the OpenTracing extension with OpenTelemetry and update your configuration accordingly.

1.4.7. Security

1.4.7.1. OIDC Client: Behavior changed if client does not have a URL

Starting in Red Hat build of Quarkus 3.20, if you use the quarkus-oidc-client extension but do not configure the OpenID Connect (OIDC) client to point to a specific URL, Dev Services for Keycloak automatically starts in dev mode.

To disable this behavior, add the following property to your application.properties file:

quarkus.keycloak.devservices.enabled=false

1.4.7.2. Security WebAuthn: Reimplementation by using WebAuthn4J

In Red Hat build of Quarkus 3.20, the quarkus-security-webauthn extension has been reimplemented by using WebAuthn4J to enhance security, align with industry standards, and improve long-term maintainability.

As a result, this update is not compatible with previous versions of the extension.

Important

This release note is provided for users of the quarkus-security-webauthn extension. Although Red Hat build of Quarkus 3.20 does not yet support this extension, be aware that this change may impact your migration.

To transition smoothly to the new implementation, use the following information.

userName changes

  • All userName references have been replaced with username.

Authenticator class changes

  • The Authenticator class (from Vert.x) is no longer used and has been replaced functionally with WebAuthnCredentialRecord. This new class holds similar data, but as a WebAuthn4J subtype, requires different methods for accessing content:

    • WebAuthnCredentialRecord.getRequiredPersistedData() returns a RequiredPersistedData record with all necessary persistence data, simplifying storage management.
    • WebAuthnCredentialRecord.fromRequiredPersistedData(RequiredPersistedData), a static method, reconstructs a WebAuthnCredentialRecord from stored data.
  • If your application stores Authenticator data in JPA entities or database tables, you must migrate to the new WebAuthnCredentialRecord format. If you encounter issues, report them in the project repository.

WebAuthnUserProvider class changes

  • findWebAuthnCredentialsByUserName() is now findByUsername().
  • findWebAuthnCredentialsByCredID() is now findByCredentialId().
  • updateOrStoreWebAuthnCredentials() has been split into the following:

    • update(String credentialId, long counter)
    • store(WebAuthnCredentialRecord credentialRecord)

Default endpoint changes

  • /q/webauthn/login is now /q/webauthn/login-options-challenge.
  • /q/webauthn/register is now /q/webauthn/register-options-challenge.
  • /q/webauthn/callback has been split into the following endpoints, which are turned off by default for security reasons:

    • /q/webauthn/login

      To enable, set the quarkus.webauthn.enable-login-endpoint property.

    • /q/webauthn/register

      To enable, set the quarkus.webauthn.enable-registration-endpoint property.

  • The new /q/webauthn/register endpoint requires a username query parameter.
  • /.well-known/webauthn has been added to return the list of allowed related origins.
  • The user name for login and login-options-challenge is now optional.
  • The /q/webauthn/login-options-challenge and /q/webauthn/register endpoints have moved from POST to GET methods and now accept parameters as query parameters instead of JSON bodies.

WebAuthnSecurity class changes

  • Two methods have been added:

    • getLoginOptionsChallenge()
    • getRegisterOptionsChallenge()
  • The username parameter for login() and loginOptionsChallenge() is now optional.
  • The register() method now requires a username parameter due to the removal of the username cookie.

Configuration changes

  • quarkus.webauthn.require-resident-key (boolean, default: false) has been replaced by quarkus.webauthn.resident-key (data enumeration, default: REQUIRED).
  • quarkus.webauthn.challenge-username-cookie-name setting has been removed along with its associated cookie.
  • The following new configuration settings have been added:

    • quarkus.webauthn.load-metadata (boolean, default: false) controls the loading of Fast Identity Online (FIDO) metadata.
    • quarkus.webauthn.user-presence-required (boolean, default: true) specifies whether user presence is required.
  • quarkus.webauthn.user-verification now defaults to REQUIRED instead of DISCOURAGED.
  • quarkus.webauthn.timeout now defaults to 5 minutes instead of 1 minute, in accordance with the WebAuthn standard.
  • quarkus.webauthn.pub-key-cred-params is now quarkus.webauthn.public-key-credential-parameters.
  • quarkus.webauthn.origin is now quarkus.webauthn.origins (plural) and now supports multiple origins, in accordance with the WebAuthn standard.
  • The following new boolean configuration options have been added:

    • quarkus.webauthn.enable-registration-endpoint (boolean, default: false) enables the default registration endpoint.
    • quarkus.webauthn.enable-login-endpoint (boolean, default: false) enables the default login endpoint.

WebAuthn credential verification changes

  • WebAuthn credential attestation verification might behave differently for quarkus.security.webauthn.attestation settings other than NONE (the default).

quarkus-test-security-webauthn test module changes

  • The WebAuthnHardware constructor now requires a URL parameter to represent the endpoint location. You can get this URL from your test classes by using @TestHTTPResource URL url.
  • WebAuthnEndpointHelper.invokeRegistration() is now obtainRegistrationChallenge().
  • WebAuthnEndpointHelper.invokeLogin() is now obtainLoginChallenge() and accepts an optional username parameter.
  • WebAuthnEndpointHelper.invokeCallback() has been split into the following:

    • WebAuthnEndpointHelper.invokeRegistration(), which requires a username parameter.
    • WebAuthnEndpointHelper.invokeLogin(), which accepts an optional username parameter.

JavaScript library changes

  • registerOnly() is now registerClientSteps().
  • loginOnly() is now loginClientSteps().
  • login() and loginClientSteps() now accept an optional user parameter.
  • The constructor parameter registerPath is now registerOptionsChallengePath (default: /q/webauthn/register-options-challenge).
  • The constructor parameter loginPath is now loginOptionsChallengePath (default: /q/webauthn/login-options-challenge).
  • The constructor parameter callbackPath has been split into the following:

    • registerPath (default: /q/webauthn/register)
    • loginPath (default: /q/webauthn/login)
  • The constructor now accepts a csrf option of type JsonObject with two keys:

    • header, which specifies the header name used to include the Cross-Site Request Forgery Prevention (CSRF) token.
    • value, which specifies the CSRF token value.

      This update improves the security of custom endpoints protected by the quarkus-rest-csrf extension. For more information, see the Quarkus Cross-Site Request Forgery Prevention guide.

The status of this feature is downgraded from preview to experimental to allow for further stabilization.

For more information, see the Quarkus Using Security with WebAuthn guide.

This change requires manual intervention. It is not included in the automated update process described in the Migrating applications to Red Hat build of Quarkus 3.20 guide.

1.4.8. Tooling

1.4.8.1. @WithTestResource flaws fixed: restrictToAnnotatedClass replaced by scope

Earlier, Red Hat build of Quarkus 3.15 shipped with a version of @WithTestResource that was flawed and was thus not announced.

In Red Hat build of Quarkus 3.20, the flaws have been fixed, resulting in a breaking change. In this release, the earlier restrictToAnnotatedClass field has been replaced by scope.

1.4.8.2. JUnit 5 Mockito: Default mocking strategy changed to inline

In earlier releases, the quarkus-junit5-mockito dependency was configured to create mock objects by using the subclass mocking strategy.

Starting in Red Hat build of Quarkus 3.20, the dependency is now configured to use an inline mocking strategy by default.

1.4.9. Web

1.4.9.1. HTTP compression now includes application/json and application/xhtml+xml by default

If HTTP compression is enabled, the quarkus.http.compress-media-types configuration property defines the list of media types to compress. In Red Hat build of Quarkus 3.20, the default value of this property has changed. Newly compressed media types now include application/json and application/xhtml+xml.

1.4.9.2. REST Client: Stricter configuration to optimize lookups

In Red Hat build of Quarkus 3.20, the REST Client Configuration became more strict to reduce the number of lookups and combinations required to retrieve the configuration:

  • The MicroProfile Rest Client config style [Simple Class Name]/mp-rest does not work anymore. The specification does not specify this style. The FQCN/mp-rest style continues to function as expected and as specified by the MicroProfile Rest Client.
  • Only REST Clients discovered by Red Hat build of Quarkus are loaded by the RestClientsConfig and RestClientsBuildTimeConfig.
  • The RestClientsConfig#clients and RestClientsBuildTimeConfig#client maps always use the Fully Qualified Collection Name (FQCN) of the REST Client interface. Before, it would use all the keys found, even if related to the same REST Client duplicating entries.
  • Removed legacy configuration names quarkus.rest.client.max-redirects and quarkus.rest.client.multipart-post-encoder-mode.

1.4.9.3. Qute: Default character escaping in JSON templates

Starting in Red Hat build of Quarkus 3.20, the quarkus-qute extension automatically escapes double quotes ("), backslashes (\), and control characters (U+0000 through U+001F) in JSON templates if a corresponding template variant is set. The extension automatically assigns a variant to templates located in the src/main/resources/templates directory.

By default, java.net.URLConnection#getFileNameMap() determines the content type of a template file. You can define additional suffix-to-content-type mappings by using the quarkus.qute.content-types configuration.

To render the unescaped value, use the raw or safe properties, which are implemented as extension methods of java.lang.Object, or wrap the string value in the io.quarkus.qute.RawString class.

For more information, see the Character escapes section of the Quarkus "Qute reference" guide.

1.4.9.4. REST Jackson: ObjectMapperCustomizer behavior changed for default JSON processor instance

In Red Hat build of Quarkus 3.20, with the quarkus-rest-jackson extension, only ObjectMapperCustomizer beans without qualifiers are applied to the default ObjectMapper instance of the Jackson JSON processor.

In earlier versions, all customizer beans, including those with custom qualifiers, were applied to the default ObjectMapper instance.

This change requires manual intervention. It is not included in the automated update process described in the Migrating applications to Red Hat build of Quarkus 3.20 guide.

For more information, see the following resources:

1.4.9.5. REST: Empty query parameters now handled as null or empty collection

In earlier releases, with the quarkus-rest extension, query parameters with empty values, such as ?foo=, were deserialized as follows:

  • @RestQuery String foo produced an empty string ("").
  • @RestQuery List<String> foo produced a collection containing a single empty string.

In Red Hat build of Quarkus 3.20, this behavior has changed:

  • @RestQuery String foo is now deserialized as null.
  • @RestQuery List<String> foo is now deserialized as an empty collection.

Update your code accordingly.

This change requires manual intervention. It is not included in the automated update process described in the Migrating applications to Red Hat build of Quarkus 3.20 guide.

1.4.9.6. WebSockets and WebSockets Client extensions deprecated

Red Hat build of Quarkus 3.20 deprecates the quarkus-websockets and quarkus-websockets-client extensions, which implement the Jakarta WebSocket specification.

Red Hat build of Quarkus plans to stop supporting these extensions in a future release.

To ensure compatibility with upcoming versions, migrate to the Quarkus WebSockets Next extension,quarkus-websockets-next, which offers a modern, more efficient WebSocket API.

For more information, see the following Quarkus resources:

This change requires manual intervention. It is not included in the automated update process described in the Migrating applications to Red Hat build of Quarkus 3.20 guide.

1.5. Additional resources

Back to top
Red Hat logoGithubredditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust. Explore our recent updates.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Theme

© 2025 Red Hat, Inc.