Changelog

 

Legend

A new feature
An existing feature has changed
A bug fix
A performance improvement
A security issue has been corrected

Smile CDR 2026.11.R01 (TBD)

 

Release Information

Released 2026-11-19
Codename TBD
HAPI FHIR Smile CDR 2026.11.R01 is based on HAPI FHIR 8.14.0, and includes all changes and fixes included in this version. Please see the HAPI FHIR ChangeLog for details about what has changed.

Upgrade Instructions

MySQL Support Removed

MySQL is no longer a supported database platform for Smile CDR, and the MySQL JDBC driver is no longer shipped with the product. MySQL had been deprecated since 2021.11.R01 because of its performance limitations. Any node whose Cluster Manager, FHIR Storage, Audit Log or Transaction Log database is configured with the MYSQL_5_7 driver type will fail to start after upgrading.

Test Utilities share one HTTP client

The clients handed out by SmileHarness in cdr-public-test-utils now issue on a single pooled HTTP client per harness, rather than each building one of their own. The following are visible to tests written against the previous release.

Clients from one harness now share a session

getAdminJsonClient(), getHL7V2RestClient(), getNpmPackageClient() and getOutboundSmartClient() previously each built a cookie store of their own, so a login through one was invisible to the others. They now all issue on the harness's HTTP client and share its cookie store, which is what lets a multi-request login flow work across them. The FHIR clients from getFhirClient(...) are unaffected — they are HAPI IGenericClients with their own transport.

Check any test that asserts a request is rejected. On the shared session such a request can now be answered as whoever logged in last, so it may pass for the wrong reason. Build it with fhirAnonymousRequest(...) or anonymousRequest(...), which send no cookies, or call harness.clearCookies() first. See Sessions, Cookies and Harness Lifecycle.

HL7V2RestClient no longer follows redirects

HL7V2RestClient.build(baseUrl, username, password) previously used Spring's auto-detected request factory, which follows redirects. It now uses the same client as every other Smile test client, which has redirect handling disabled — so a 3xx is returned as-is, matching AdminJsonRestClient and NpmPackageClient. A test that relied on the redirect being resolved must follow the Location header itself.

The client is now AutoCloseable. One you build yourself with build(...) owns the connection pool behind it and should be closed when the test is done with it. One obtained from a harness borrows the harness's pool, so closing it leaves that pool up for the harness's other clients.

RequestFactoryUtil.buildSmileRequestFactory() removed

Use RequestFactoryUtil.wrap(...) instead, passing a client you own — or, inside a test, the one SmileHarness.getHttpClient() already holds, so the resulting RestClient shares the harness's session and pool:

RestClient restClient = RestClient.builder()
    .requestFactory(RequestFactoryUtil.wrap(harness.getHttpClient()))
    .baseUrl(baseUrl)
    .build();

SmileHarness gained methods and is now AutoCloseable

The interface declares the new request builders (fhirRequest, fhirAnonymousRequest, request, adminJsonRequest, anonymousRequest, getHttpClient, clearCookies, close). A custom implementation of SmileHarness must implement them; tests that only use the interface need no change.

SmileCdrContainer.getHarness() caches its harness

It returns the same harness on every call instead of a new one, and closes it when the container stops — so you do not need to close a container-supplied harness yourself. A harness reads the node's module configuration once, when it is built; after changing module configuration through the Admin JSON API, call container.refreshHarness() and use the harness it returns.

MockHttpServer removed

The class was an empty placeholder and had no implementation to replace.

JavaScript Execution Environment Remote Debugging in Docker

Debugging a Smile CDR server's JavaScript Execution Environment in a dockerized environment will now no longer work in all cases.

This is due to a security fix. Check the documentation for details.

Changes

The Persistence module now warns at startup when Search Parameter Seeding patterns disable built-in terminology SearchParameters on CodeSystem, ValueSet, or ConceptMap, which can impair terminology and validation features. Malformed enable/disable patterns (e.g. :patient instead of *:patient) are also now rejected with a clear configuration error rather than an obscure startup failure.

A FHIR endpoint secured with SMART on FHIR must serve its CapabilityStatement (CS) to unauthenticated client applications as they may fetch the CS before holding an access token. The FHIR REST Endpoint, FHIR Gateway and Hybrid Providers modules now report a configuration warning when such an endpoint has anonymous access disabled, or when the anonymous account is missing the FHIR_CAPABILITIES permission. Refer to our documentation for details.

Smile CDR now supports running in a container with a read-only root filesystem. When read-only filesystem mode is enabled, logging is routed to stdout only so that nothing is written to the installation directory. See Read-Only Filesystem Support for more information.

An MDM module configured with mdm.mode set to MATCH_ONLY now starts and runs without an MDM license. The default MATCH_AND_LINK mode still requires an MDM license.

Entries in the SMART Outbound Security module's Allowed Audience List can now end with a {partition} placeholder, which accepts any aud value whose final path segment is a partition name, so deployments using URL-based partitioning no longer need one entry per tenant.

Generally Available (GA) Releases are stable for production. A non-GA release (eg: PRE releases) will now log a warning on startup. Additionally a banner warning will appear in web-admin console.

The CDA Exchange+ module now supports Instruction entries in the Plan of Treatment section. These entries map to CarePlan resources.

Added a property "ignore placeholder resources". If set true, MDM matching will skip placeholder resources during matching (by default, this is false to preserve existing functionality).

Added configuration options to set warning and max thresholds for MDM matching. For how MDM matching, deduplication and bundle matching handle a resource that reaches the max threshold, see Resources Omitted From MDM Matching.

The CDA Exchange+ module maps a Comment Activity entry embedded within a Medication Activity onto the note field of the corresponding MedicationStatement or MedicationRequest resource.

The CDA Exchange+ module now supports mapping from an Instruction entry relationship within a Medication Activity entry onto corresponding fields of the MedicationStatement and MedicationRequest resources.

The CDA Exchange+ module now supports the Procedure Activity Act entry in the Procedures section. These entries map to Procedure resources.

The CDA Exchange+ module now supports a Comment Activity entry embedded within a Procedure Activity Procedure element.

The CDA Exchange+ module now supports Advance Directive Observations and Advance Directive Organizers within the Advance Directives section.

The CDA Exchange+ module now supports the Assessment Scale Observation as an entry in the Functional Status section.

The CDA Exchange+ module now supports a Comment Activity entry embedded within a Family History Observation element.

The CDA Exchange+ module now supports the Health Status Observation as an entry in the Health Concerns Section.

The CDA Exchange+ module now supports the Precondition for Substance Administration element within a Medication Activity entry, for the data import path only.

The CDA Exchange+ module now supports the Medical (General) History section as a narrative-only section.

SmileHarness in the Test Utilities can now issue a raw HTTP request against any module it can reach, so that a test can assert on the response itself — a status code, a response header, or a redirect returned rather than followed. The fhirRequest(...), adminJsonRequest(...) and request(...) builders carry the harness credentials and session. The fhirAnonymousRequest(...) and anonymousRequest(...) builders carry neither. Other test-utility APIs changed alongside this. See the upgrade notes.

The Test Utilities REST clients now name their connection-pool ownership at the call site. AdminJsonRestClient, HL7V2RestClient and NpmPackageClient gain open(...), openAnonymous(...) and issuingOn(theHttpClient, ...): anything opened owns a pool the caller has to close, and anything built with issuingOn(...) borrows a pool that stays the caller's. The existing build(...) and buildAnonymous(...) factories are deprecated but still work; they named neither case.

Smile CDR now includes a customer/ directory containing customer/classes and customer/lib, both of which are added to the server classpath at startup. These directories hold nothing but a README in a new installation and are intended for deployments that supply custom scripts, resources, and JAR files through a filesystem bind mount, without overlapping the directories that ship with Smile CDR. See Mounting Customizations with Bind Mounts.

Added unauthenticated /startup and /readiness endpoints on a dedicated status port, reporting whether the process has started and whether its modules are healthy, for use as Kubernetes startup and readiness probes. The endpoints are off unless node.status.port is set in the node configuration.

Added an unauthenticated /liveness endpoint on the node status port, for use as a Kubernetes livenessProbe. It reports only on health checks that a process restart can fix, and ignores all others, so a failing dependency such as a database never restarts the process.

Added a memory_pressure health check that fails /liveness when a process is so short of memory that it has spent most of its time on garbage collection for several minutes. It does not clear until the process restarts. The Kubernetes deployment guide now enables livenessProbe and covers JVM memory settings.

The Pre-Assigned Patient Identifier Systems and Document Repository features now work on any FHIR Storage (RDBMS) module with a Patient ID Partitioning mode enabled. Previously these features only worked when MegaScale was in use.

Previously, when SAML authentication was enabled on a Web Admin Console module, the console login page offered no way to initiate the SAML login flow; users had to browse directly to the /saml2/authenticate/REGISTRATION_ID URL. The login page now displays a Sign in with SSO link that initiates the SAML authentication flow with the configured Identity Provider. The text of this link can be customized with the new Web Admin Console setting SSO Button Label (signin.sso_button_label).

Azure Blob Storage binary storage can now authenticate using Azure Managed Identity or Workload Identity instead of a stored account key, client secret or SAS token. See External Object Storage for details.

The Batch Job endpoint response for fetching batch jobs by filters (GET /batch2-jobs/modules/{module_id}) now includes a totalRecords field that reports the total number of jobs matching the filters. See Fetch Batch Jobs by Filters.

SmileHarness in the Test Utilities now reaches modules configured with a context_path, through its clients and request builders alike; the Admin JSON module's context path is given in HarnessContext, and SmileCdrContainer reads it from the properties file. The harness also gains a CdsHooksClient, client credentials, token introspection, token refresh and OpenID Connect discovery on OutboundSmartClient, and FHIR access with a bearer token. Where a node has several modules of one type, the no-argument accessors now choose one deterministically, and getHL7V2RestClient() uses the discovered HL7v2 endpoint rather than port 7000.

Request and Response validation for the Claim/$submit operation has been moved from the HTTP Operation and into optional Camel processors. The two new processors, pasRequestBundleValidator and pasResponseBundleValidator, are now available for use in PAS Camel routes. PAS requests and responses will no longer be validated unless these processors are used.

The MDM documentation now describes the concurrency risks of raising the MDM module's consumer_count setting above 1. Concurrent matching threads can create duplicate Golden Resources for the same person, so the setting should be left at its default of 1 unless the documented trade-offs and duplicate cleanup effort are acceptable.

Previously, when using the smileutil synchronize-fhir-servers command with the parameter --prefix-numeric-ids, the command would raise an exception if a resource being processed contained a reference to another resource whose type was not included in the list of supported resource types. This constraint has been removed.

The documentation search in the Web Admin Console help pages now queries the same hosted documentation search index as smilecdr.com, returning results for the running Smile CDR version grouped by page and section. The search requires outbound HTTPS access to the documentation search service; when it cannot be reached the search shows a "search unavailable" message.

The HL7v2 MLLP inbound listener now supports an optional maximum_message_size.bytes setting that bounds the size of a single inbound message. This setting defaults to unlimited, preserving prior behaviour.

The HL7v2 MLLP inbound listener now supports an optional maximum_message_timeout.millis setting that limits the total time allowed to receive a single inbound message. A connection that takes longer than this limit is closed. This setting defaults to unlimited, preserving prior behaviour.

The HL7v2 MLLP inbound listener now supports an optional maximum_connections setting that limits the number of concurrent connections the listener will accept. This setting defaults to unlimited, preserving prior behaviour.

The $log-questionnaire-errors operation, in the Prior Auth PAS module, will now pass the operation request parameters to the direct:log-questionnaire-errors Camel route. This allows custom downstream handling of the operation. The operation will still validate, persist and return the passed OperationOutcome. The new Camel route must be provided. Deployments that have not configured a route consuming direct:log-questionnaire-errors will receive an HTTP 500 error when the operation is invoked.

The Prior Auth PAS module's Claim/$inquire operation now routes the request through the module's Camel context via the direct:start-pas-inquire route, so the inquiry can be forwarded to a payer or adjudication system instead of always being answered from the local repository. Two Camel processors are shipped for the route: pasInquiryRequestBundleValidator validates the inquiry request bundle, and createInquireResponseProcessor retrieves the latest adjudication response from the local repository and generates the PAS inquiry response. Note that Claim/$inquire previously did not use a Camel route at all, so an existing deployment must add a direct:start-pas-inquire route to its PAS routes file before upgrading, or the operation fails with HTTP 500. See Prior Auth PAS for the route contract and PAS Payer Setup for an example route.

MySQL is no longer a supported database platform, and the MySQL JDBC driver is no longer shipped with Smile CDR. Modules configured with the MYSQL_5_7 driver type will fail to start. See the upgrade notes for migration guidance.

Previously the swagger ui request to list openid connect servers (GET /openid-connect-servers) was incorrectly passing the pageSize parameter.

Previously, downloading the system configuration bundle with Include Logs enabled from the Admin Console (or the /system-config endpoint) would throw an OutOfMemoryError if a single log exceeded approximately 2 GB. This technical limitation has now been removed, and log files over 2 GB now download successfully.

Previously, a bulk export initiated by a SMART client holding a filtered read-only scope, such as system/*.r?code=foo, ignored the scope filter and could export resources outside it. The filter of a read-only scope now restricts the export contents for resource types that no search scope covers. Search scope filters continue to take precedence for the types they cover.

Previously, when using Pulsar as the message broker, a restarted module (e.g. MDM) could be unable to send messages, because Pulsar rejected its new producer while the old one still held the same name, and the old producers stayed connected until Smile CDR shut down. Pulsar now names each producer, and a module closes its producers, including those used by Realtime Export, channel retry and the transaction log broker, when it shuts down. A PULSAR_PRODUCER_BUILDER interceptor that sets a fixed producer name can still cause the original problem; see Pulsar.

Previously, when a document Bundle was created in a transaction with MegaScale Document Repository mode enabled, a NullPointerException could occur if a resource in the document contained a Reference with no reference value (e.g. an identifier with an assigner that only has the display element populated). This has been fixed.

The FHIR_EXTENDED_OPERATION_ON_SERVER permission for the $partition-management-list-partitions operation is no longer part of the appSphere administrator role. The Admin Console and Developer Portal now read repository partition data from the FHIR CapabilityStatement instead of invoking that operation, so the permission is no longer required. Accounts that were granted it directly, rather than through the role, keep it; it is unused and can be removed manually.

Previously, when the target (ingesting side) of a P2P $sdh.s2s.invoke-export used the PATIENT_ID partition selection mode, resources ingested before the Patient could be stored outside the patient's partition, leaving them unreachable from patient compartment queries even though the job reported COMPLETED. Ingestion now waits for the Patient to be ingested before ingesting the resources that reference it, and fails the job if the Patient never arrives. A PATIENT_ID-partitioned target must use the UUID server ID strategy.

Previously, a search that was automatically narrowed to a very large number of compartments (for example for a user with tens of thousands of FHIR_READ_ALL_IN_COMPARTMENT permissions) could exceed the database's parameter limit, causing the query to fail. These searches now succeed on PostgreSQL, Oracle and SQL Server (level 130+). The number of values at which this behaviour applies can be changed with the new Bind ID List as JSON Above Size setting.

Previously, Observation resources derived from CDA Advance Directive Observation entries were not being assigned a category code. This has been changed to assign the category http://terminology.hl7.org/CodeSystem/observation-category|social-history.

Package loading now matches HTTP redirect targets against the package URL whitelist before following them. See Package URL Redirects for details.

The FHIR Storage module now restricts the locations from which NPM packages (Implementation Guides) can be loaded. Previously packages could be loaded from any file, classpath, or remote URL. Administrators must now configure a whitelist of permitted URL prefixes via the package.url.whitelist.text or package.url.whitelist.file setting. No whitelist ships by default, so all package installs are rejected until one is configured. See Allowed Package URLs.

Channel Import and the Smile Camel processors can now restrict which FHIR partitions an inbound message may access, closing a cross-partition read/write escape when configured. Set the permitted partitions via the Channel Import module's new Allowed Partitions setting, or the allowedPartitions route parameter on any Camel processor that resolves a partition from a message (bundleProcessor, singleResourceProcessor, channelImportProcessor, patientMergeProcessor, replaceReferencesProcessor, and the terminology processors). Each accepts a comma-separated list of partition IDs and/or names. The restriction is opt-in: the setting defaults to _ALL (every partition permitted), so existing deployments are unaffected until an explicit list is configured. A partition set by the operator-configured Camel partitionId route parameter remains trusted, and enforcement applies only when persistence partitioning is enabled.

Previously, a JavaScript Execution Environment script could call getClass() on an object passed to it and use Java reflection to load any Java class, bypassing the Class Allowlist. This has been fixed. Other public methods on objects passed to scripts, and classes in the Class Allowlist, are unaffected.

Previously, the JavaScript Execution Environment parseResponseAsJson() method parsed and executed any response body. This means arbitrary JavaScript in the response could be executed. This method now only successfully parses JSON responses, while other responses that are not strict JSON will now be rejected and throw a SyntaxError.

Previously, the Debug Host Address configuration parameter for JavaScript Execution Environment Remote Debugging was being ignored. This has been fixed. This is a breaking change in certain debugging environments (notably those in a dockerized environment). Refer to the documentation for more information.

Smile CDR 2026.08.R02 (Evolution)

 

Release Information

Released 2026-09-14
Codename Evolution
HAPI FHIR Smile CDR 2026.08.R02 is based on HAPI FHIR 8.12.1, and includes all changes and fixes included in this version. Please see the HAPI FHIR ChangeLog for details about what has changed.

Upgrade Instructions

Importing LOINC

The mechanism used to import the LOINC CodeSystem has been completely redesigned for better performance and visibility. See Uploading LOINC for information about the new mechanism.

FHIR Gateway inclusion behavior change

To fix duplicate resources appearing on multiple pages of paginated Patient/$everything responses (GL-8701), the FHIR Gateway now uses the HAPI default BASED_ON_INCLUDES bundle-inclusion rule (previously BASED_ON_RESOURCE_PRESENCE).

A side effect of this fix is that the gateway no longer relays referenced resources that a target server attaches to a search response on its own initiative.

  • Searches that use _include or _revinclude are unaffected; the resources each target returns as search.mode = include still come through.
  • Plain searches that previously received target-volunteered referenced resources now receive only the matched resources. Clients that want included resources must request them with _include or _revinclude.
  • Patient/$everything has the same include set as before; the only observable difference is that cross-page duplicates no longer occur.

JSON Admin API MDM endpoints deprecated

The MDM endpoints on the JSON Admin API (under /mdm/{module_id}/...) are deprecated as of 2026.08.PRE and are scheduled for removal in 2028.08.R01 or later (GL-8729). They are flagged deprecated: true in the generated OpenAPI spec.

Use the corresponding FHIR $mdm-* operations on the cdr-endpoint-fhir module instead, so requests pass through the platform's full authorization model. See the JSON Admin API MDM Deprecation Migration guide for the full endpoint mapping.

The mdm-algorithms and mdm-metrics endpoints on the JSON Admin API are not deprecated.

CDA Exchange (legacy) module removed

The deprecated CDA Exchange module (module.cda.type=CDA_EXCHANGE) has been removed.

See CDA Exchange Plus for configuration details.

FHIR_OP_INITIATE_BULK_DATA_IMPORT permission removed from SMART scope

The FHIR_OP_INITIATE_BULK_DATA_IMPORT permission is no longer implicitly granted through SMART authorization. To grant this permission in a SMART session, use the callback function onSmartScopeAuthorityNarrowing().

LDAP Inbound Security module requires a system user password

Spring LDAP has been updated to address CVE-2026-41720. An LDAP bind that supplies a distinguished name together with an empty password is an unauthenticated bind under RFC 4513, and is now rejected. Note that user authentication in the LDAP Inbound Security Module is unaffected, as empty passwords were already rejected before reaching Spring LDAP.

What this does affect is the module's system user connection, which is used to search the directory. Before upgrading, check whether ldap.systemuser.dn is configured while ldap.systemuser.password is left blank. Such a module will no longer start.

To resolve, either set a password for the system user, or clear ldap.systemuser.dn so that the module connects to the directory anonymously. A blank DN together with a blank password remains a valid anonymous connection and is unaffected.

AppSphere Sandbox Deprecated

The Sandbox functionality in the AppSphere module has been deprecated. Clients are advised to set up a separate AppSphere module in their lower environments for developers to register account and application(s) for testing purposes.

Changes

Smile CDR 2026.08.R01 (Evolution)

 

Release Information

Released 2026-08-27
Codename Evolution
HAPI FHIR Smile CDR 2026.08.R01 is based on HAPI FHIR 8.12.0, and includes all changes and fixes included in this version. Please see the HAPI FHIR ChangeLog for details about what has changed.

Upgrade Instructions

Importing LOINC

The mechanism used to import the LOINC CodeSystem has been completely redesigned for better performance and visibility. See Uploading LOINC for information about the new mechanism.

FHIR Gateway inclusion behavior change

To fix duplicate resources appearing on multiple pages of paginated Patient/$everything responses (GL-8701), the FHIR Gateway now uses the HAPI default BASED_ON_INCLUDES bundle-inclusion rule (previously BASED_ON_RESOURCE_PRESENCE).

A side effect of this fix is that the gateway no longer relays referenced resources that a target server attaches to a search response on its own initiative.

  • Searches that use _include or _revinclude are unaffected; the resources each target returns as search.mode = include still come through.
  • Plain searches that previously received target-volunteered referenced resources now receive only the matched resources. Clients that want included resources must request them with _include or _revinclude.
  • Patient/$everything has the same include set as before; the only observable difference is that cross-page duplicates no longer occur.

JSON Admin API MDM endpoints deprecated

The MDM endpoints on the JSON Admin API (under /mdm/{module_id}/...) are deprecated as of 2026.08.PRE and are scheduled for removal in 2028.08.R01 or later (GL-8729). They are flagged deprecated: true in the generated OpenAPI spec.

Use the corresponding FHIR $mdm-* operations on the cdr-endpoint-fhir module instead, so requests pass through the platform's full authorization model. See the JSON Admin API MDM Deprecation Migration guide for the full endpoint mapping.

The mdm-algorithms and mdm-metrics endpoints on the JSON Admin API are not deprecated.

CDA Exchange (legacy) module removed

The deprecated CDA Exchange module (module.cda.type=CDA_EXCHANGE) has been removed.

See CDA Exchange Plus for configuration details.

FHIR_OP_INITIATE_BULK_DATA_IMPORT permission removed from SMART scope

The FHIR_OP_INITIATE_BULK_DATA_IMPORT permission is no longer implicitly granted through SMART authorization. To grant this permission in a SMART session, use the callback function onSmartScopeAuthorityNarrowing().

LDAP Inbound Security module requires a system user password

Spring LDAP has been updated to address CVE-2026-41720. An LDAP bind that supplies a distinguished name together with an empty password is an unauthenticated bind under RFC 4513, and is now rejected. Note that user authentication in the LDAP Inbound Security Module is unaffected, as empty passwords were already rejected before reaching Spring LDAP.

What this does affect is the module's system user connection, which is used to search the directory. Before upgrading, check whether ldap.systemuser.dn is configured while ldap.systemuser.password is left blank. Such a module will no longer start.

To resolve, either set a password for the system user, or clear ldap.systemuser.dn so that the module connects to the directory anonymously. A blank DN together with a blank password remains a valid anonymous connection and is unaffected.

AppSphere Sandbox Deprecated

The Sandbox functionality in the AppSphere module has been deprecated. Clients are advised to set up a separate AppSphere module in their lower environments for developers to register account and application(s) for testing purposes.

Changes

The Web Admin Console User Management page now includes a Show Disabled Users toggle. When enabled, disabled user accounts appear in the listing alongside active accounts, allowing administrators to re-enable them directly through the Modify action. Previously, disabled users were hidden from the listing and could only be re-enabled via the JSON Admin endpoint.

Added the $sdh.mdm-deduplicate operation, which finds duplicate FHIR resources using MDM matching rules and merges confirmed matches via a Batch2 job. The operation runs asynchronously: it returns a poll URL, and $sdh.mdm-deduplicate.poll-for-status reports job progress and returns the merge report on completion. It supports preview mode and configurable delete-source behavior. The operation is currently available for R4.

Added a new compressed token indexing strategy for token search parameters that can reduce overall database storage by up to 20%. The strategy is configurable on the persistence module via the new Token Index Write Targets and Token Index Read Target settings. See Compressed Token Indexing for configuration and migration details.

MegaScale repositories now support basic searching across multiple shards (i.e. searches where the requested partition list contains partitions spanning multiple database instances). This functionality has some limitations, described here.

A new built-in smile:validate Camel processor has been added, allowing FHIR resources to be validated inline within a Camel route without an HTTP round-trip to the $validate operation. See the documentation for more information.

FHIR Storage (RDBMS) modules have a new ID Sequence Pooling Strategy setting. The default preserves the existing behaviour. The new PER_THREAD_POOL option can improve throughput on write-heavy workloads by reducing contention between concurrent writers. This setting can not be changed with a zero-downtime upgrade. It must be applied to all servers uniformly.

The /.well-known/smart-configuration endpoint now includes grant_types_supported (reporting authorization_code and client_credentials) and code_challenge_methods_supported (reporting S256) in its JSON response. These fields are required by the SMART App Launch STU2 specification (Inferno test 1.1.02) and were previously absent when Smile CDR was fronting an external Authorization Server such as PingOne AIC.

Added custom scheduled jobs, allowing batch jobs and Camel routes to be invoked on a recurring Quartz schedule via the JSON Admin API or web admin UI. For more details see Custom Scheduled Jobs Overview.

Added the ability to capture system log lines emitted during a transaction and attach them as a SYSTEM_LOG step on the parent Transaction Log entry. Disabled by default; see Capturing System Logs for more details.

Module configuration property frame_options.csp_frame_ancestors was added to explicitly set the Content-Security-Policy: frame-ancestors HTTP header directive in server replies to browser requests. This is the modern replacement to X-Frame-Options: ALLOW-FROM which is no longer supported by current browsers. Refer to our documentation for further details on the above headers, their security implications and configuration.

Added the AWS MSK IAM library to the Smile CDR distribution to make it easier for SmileFactory Deployer to integrate with Smile CDR.

The HL7 v2.x inbound listener script now supports a new optional callback, onPreQueryResponse(theResponse, theContext), invoked once per RSP^K23 response built in reply to an inbound query (e.g. QBP^Q21) before the response is logged and sent back. See Inbound HL7 v2.x: Callback Scripts for details.

The CrdToCqlRequestProcessor will now pass the "selections" context key from the CDS Hook request to the $r5.apply call in a new parameter called selections.

Added new roles and permissions for the Provider Access API and Terminology Mapping applications in Smile Portal.

Added a new configuration option Bulk Export Resource-Level Auditing on FHIR endpoint modules. When enabled, downloading a Binary resource produced by a bulk $export job generates an audit event of type FHIR_BULK_EXPORT_BINARY_DOWNLOAD that includes individual resource references for each resource contained in the NDJSON file, rather than only auditing the Binary resource itself. This setting is disabled by default.

The Prior Auth CRD module now validates the davinci-crd.version extension at CDS Hook registration time. A warning is logged if the extension is missing or improperly formatted.

The importer used to import the LOINC CodeSystem has been completely redesigned to use a batch process instead of a hidden background task. This means that LOINC importing now has much better performance and much better job visibility. See Uploading LOINC for information on the new importer.

When a missing-translation-suggestion Task cannot be completed — the source resource referenced by the Task focus cannot be resolved, or the suggestion provider fails for any reason (for example a remote service is unreachable, returns an error or an unparseable response, or the source resource has no supported mapping) — the Task status is set to failed with the failure reason recorded in the Task status reason.

Added a preview West Coast Informatics (WCI) missing-translation-suggestion provider.

A new INGESTION_DASHBOARD application type has been added to the Product Portal, with an INGESTION_DASHBOARD_ADMIN role that grants permissions to access the Admin JSON API, Transaction Log, and Transaction Log Events.

Smile Portal can now host customer web applications packaged as web-jars placed in /customerlib, without any Java code changes. Each app is exposed under a configured application type and served at extra-apps/{pathSlug}/, gated by the SMILE_PORTAL_OF_TYPE permission for that type. A web-jar declares the custom application type(s) it contributes through a META-INF/smile/application-types-v1.json file rather than compiled Java, and its assets are resolved from the standard web-jar layout with the version read from the web-jar's Maven metadata. Configure hosted apps via the new internalApps section of the Smile Portal application config.

Added job instance ID to FHIR request transaction logs for P2P module operations. When a P2P operation such as $invoke-export, $bulk-member-match and $provider-member-match starts a batch job, the job instance ID is now captured as an additional property in the transaction log, enabling direct linking between the originating FHIR request and its corresponding batch job.

Added Bulk Batch Replication module type (REALTIME_EXPORT_BULK_BATCH_REPLICATION) that periodically replicates a window of FHIR resource version history in bulk to a pluggable target IRepository implementation, such as an analytical data lake. For more details see Bulk Batch Replication.

A Danger check has been added that fails a merge request when a changelog entry added in the MR is placed in the wrong version directory for the target branch. The expected directory is derived from the project pom version (for example a 2026.08.PRE pom requires entries in changelog/2026_08_R01); the check is skipped when the pom version is not a .PRE pre-release.

Added a StatelessCrdEngineProcessor for Prior Auth CRD Camel Routes that can be used to generate unique coverage-assertion-id extension for stateless CRD engine responses. The coverage-assertion-id extension is required by the Da Vinci CRD specification to uniquely identify coverage assertions, and will be used to correlate CRD evaluations with downstream DTR $questionnaire-package requests, enabling DTR to route requests back to the appropriate CDS engine without the client needing to repeat the original CRD context.

Added a new transaction log step BATCH_JOB_RESULT_SUMMARY to $bulk-member-match batch job completions. The step records match group resource ID, request member count, and per-bucket member counts (matched, non-matched, consent-constrained). A new configuration option Audit Member Identifiers in TX Log on the Data Exchange module controls whether member identifiers are included in the summary: matched members are identified by patient identifier (system|value), while non-matched and consent-constrained members are identified by their contained resource UUID for deep-linking into the full response. This setting is disabled by default.

The Transaction Log JSON Admin API /transaction-log endpoint now accepts multiple comma-delimited eventSubType values (for example eventSubType=FHIR_OPERATION_SDH_CDA_TO_FHIR,FHIR_TRANSACTION), returning events that match any of the listed subtypes.

The System to System Data Exchange module now includes the configured federationRequestScopes when requesting an access token from a source server. The scope is propagated for both the CLIENT_SECRET_BASIC and PRIVATE_KEY_JWT client authentication methods, and is omitted when no scope is configured.

Added job instance ID to FHIR request transaction logs for Bulk Data export operations. When a $export or $davinci-data-export operation starts a batch job, the job instance ID is now captured as an additional property in the transaction log, enabling direct linking between the originating FHIR request and its corresponding batch job.

The CDA Exchange module now supports a new TRANSACTIONAL_MDM import mode. When enabled, the FHIR transaction bundle produced from an inbound CDA document is processed through the $sdh.mdm-bundle-match operation before persistence, so incoming resources are matched and consolidated against existing MDM-managed records. This mode requires a Master Data Management (MDM) module dependency.

The Hl7v2 Inbound module now supports a new MDM Deduplication mode. When enabled, the FHIR transaction bundle produced from an inbound HL7v2 message is processed through the $sdh.mdm-bundle-match operation before persistence, so incoming resources are matched and consolidated against existing MDM-managed records. This mode requires a Master Data Management (MDM) module dependency.

The logged response from the Prior Auth CRD flow now contains the name of the dynamic Camel route used, enabling downstream correlation between CRD and DTR requests.

A new Camel processor, crdCoverageAssertionIdCache has been added to the CRD module. This processor can be used to cache the response from the CRD flow when using a stateless evaluation engine, enabling correlation between the CRD request/response and the subsequent DTR request.

A new MEMBER_MATCH_CONSENT_VALIDATION interceptor pointcut has been added. It is invoked after a patient is matched during the $member-match operation and allows clients to run custom consent validation logic (including JavaScript) against the matched Patient, the Coverage to match, and the Consent resource. Hooks may return a Boolean: true if the consent determination is valid, or false if the consent is constrained. If a non-Boolean value is returned, the default consent validation is used.

When the Cluster Manager boots with a Kafka message broker, the Kafka client now introspects the broker and logs the broker's version information and the lower and upper bounds of client compatibility at INFO level. This information is also included in the cdr-system-config ZIP export from the admin JSON endpoint, in a new file called broker-information.txt.

The $member-match, $bulk-member-match, and $provider-member-match operations now support operation-specific custom JavaScript match functions. Clients can define payerMatchPatient (used by $member-match and $bulk-member-match) and providerMatchAndValidateRelationship (used by $provider-member-match), for both synchronous and asynchronous requests. When the operation-specific function is not defined, the system falls back to the existing matchPatient function, so previously configured scripts continue to work unchanged. The request passed to these functions now also exposes the Consent resource, allowing custom matching logic to take the submitted consent into account.

The $member-match, $bulk-member-match, and $provider-member-match operations now support operation-specific custom JavaScript consent-validation functions, invoked after a patient is matched. Clients can define payerValidateConsent (used by $member-match and $bulk-member-match) and providerValidateConsent (used by $provider-member-match), for both synchronous and asynchronous requests. Each function receives the matched Patient, the Coverage to match, and the submitted Consent, and should return a Boolean: true if the consent determination is valid, or false if the consent is constrained. When no operation-specific function is defined, the default consent validation is used; if a defined function returns a non-Boolean value, the default consent validation is used and a warning is logged.

Added an opt-in auto-approval mechanism to the appSphere module. When the new Auto-approving for Public and Confidential registrations setting is enabled, a scheduled job automatically approves submitted application registrations without administrative review, moving Public and Confidential (client secret) registrations to Live and creating their OpenID Connect client, while leaving JWKS-based registrations In Review. This is intended for dedicated testing zones only and is disabled by default; enabling it raises a module configuration warning.

appSphere developers can now generate an approved application's OIDC client secret on demand from the Developer Portal. It is returned exactly once, only its hash is persisted, and it inherits the expiry of the secret it replaces, which is invalidated immediately. Stored plaintext secrets have been removed (the AG_APPL.SEED column is scrubbed and will be removed in a future release), so existing applications must generate a new secret to obtain a usable one. A new AG_OAUTH2_CLIENT_SECRET_REGENERATED pointcut delivers each generated secret to interceptors, so it can be propagated to an external Identity Provider.

The PATIENT_ID and BUCKETED_PATIENT_ID partition modes now support conditional references to Patient resources, as well as auto-creating placeholders for these references when there is no matching Patient. This depends on storage that supports an all-partition search. Patient entries referenced by urn placeholders or by inline match URLs are resolved to a concrete Patient independently of entry order, an unmatched conditional Patient is created with a server-assigned id when the server id strategy is UUID, duplicate conditional creates of the same match URL within one bundle consolidate into a single Patient that is guarded against concurrent duplicate creation, and each entry's OperationOutcome reports the outcome of the caller's original request.

The transaction log emitted by the summary/completion step of the $bulk-member-match batch job has been updated to include the jobInstanceId and jobDefinitionId for easier correlation with other batch job steps.

The $member-match, $bulk-member-match, and $provider-member-match operations can now represent a matched member that has no local Patient resource, such as a member matched at an external plan by a custom match function. The matched Patient is preserved verbatim as a contained resource on the matched-members Group, and the group member entity references it with a fragment reference. The contained resource id is deterministic but opaque: consumers must not rely on any format or prefix. For such members no Consent resource is written during the match (the remote plan remains the system of record for the consent attestation), and the provider-access consent opt-out evaluation passes them through unchanged instead of failing. Additionally, the consent-constrained Group returned by $provider-member-match now uses the provider-specific no-match profile, consistent with the non-matched Group.

Member Match operations now support providing multiple business identifiers using the auth-business-identifiers key. For more details see the P2P Auth Registration Docs.

The MEMBER_MATCH_CONSENT_VALIDATION interceptor pointcut, along with the payerValidateConsent and providerValidateConsent custom JavaScript consent-validation functions, now also receive the matched Patient resource (the patient resolved during the match), accessible via IMemberMatchConsentRequest#getMatchedPatient(). This allows custom consent-validation logic to inspect the matched Patient in addition to the member Patient, the Coverage to match, and the submitted Consent. The matched Patient may be absent for members that have no local Patient resource, such as those matched at an external plan by a custom match function.

The $member-match operation now stamps a business identifier extension on the persisted Consent resource. This extension records the primary business identifier of the requesting payer.

The compressed token index's dictionary table CDH_SPIDX_TOKEN_COMMON and system-URL table HFJ_RES_SYSTEM are now reference tables on Citus and AWS Aurora Limitless, enabling node-local joins for token searches instead of cross-shard lookups.

A new setting has been added to the Subscription modules. scheduled_tasks.async_persisted_resource_processing.batch_size allows configuration of the size of the batch of messages that is sent at once to a subscription topic. This was previously one resource at a time, which was caused a performance bottleneck, the symptom of which was lagging subscriptions in high-write environments. The default value for this field is 1000.

Token searches against the compressed token index now match all of their hashes with a single IN (...) clause instead of a chain of OR'ed equality comparisons, which could lead the database to discard the token index and read the whole table. This matters most for an unqualified chained search (e.g. Observation?subject.identifier=system|value). Search results are unchanged.

The deprecated CDA Exchange module (module.cda.type=CDA_EXCHANGE) has been removed.

The AdminJsonRestClient test utility methods updateModuleConfig and restartModule (in cdr-public-test-utils) now wait for the target module to return to a STARTED status before returning (90-second timeout, 500 ms poll interval), eliminating the race condition between config changes and subsequent test calls. The wait is applied by default via short-form overloads; longer-form overloads accept an explicit boolean shouldWaitForRestart to opt out, and a further Duration argument to override the default timeout.

Smile CDR now provides a docker image that is based on Redhat Universal Base Image 9, in addition to the current offering that is based on Alpine Linux. It can be retrieved by adding the -ubi suffix to any versioned docker container. e.g. docker pull docker.smilecdr.com/smilecdr:2026.08.R01-ubi.

The MDM endpoints in the JSON Admin API (/mdm/{module_id}/...) have been deprecated in favour of the corresponding $mdm-* operations on the cdr-endpoint-fhir module. Calls to the admin-json variants will continue to work for now and are flagged deprecated: true in the generated OpenAPI spec; the deprecated endpoints are scheduled for removal in 2028.08 or later. The mdm-algorithms and mdm-metrics endpoints are not affected. See the JSON Admin API MDM Deprecation Migration guide for the full mapping.

The CRD service ext-coverage-information extension has been updated for Da Vinci CRD v2.2.0 compliance. New sub-extensions are now supported: info-needed, doc-purpose, expiry-date, billingCode, and reason. The doc-needed sub-extension now supports multiple instances (the removed 'both' value is replaced by repeating doc-needed entries). The detail sub-extension now includes a mandatory category field.

Updated the order-dispatch CDS hook prefetch template to align with the latest IG recommendations. The prefetch now uses individual resource type queries with FHIRPath expressions on context.dispatchedOrders instead of the previous bundled query format.

The System to System Data Exchange module now resolves the OAuth2 token endpoint for every outbound token request using a single precedence rule. When the OIDC Server definition sets federationTokenUrl, that URL is used directly and no .well-known discovery request is made. Otherwise, when authWellKnownConfigUrl is set, it is fetched exactly as configured, including any query string, and its token_endpoint is used; an error is raised if the fetched document has no token_endpoint, and the configured URL is written to the log rather than to the error message. When neither URL is set, the token endpoint continues to come from {fhirEndpointUrl}/.well-known/smart-configuration. Each resolution is logged at INFO, naming the server, the resolved token endpoint and which of the three rules supplied it. As a result, authWellKnownConfigUrl is no longer a required field on System to System Data Exchange OIDC Server definitions, while fhirEndpointUrl remains required. The fallback patient search performed during $sdh.s2s.invoke-export now uses the same client authentication flow as the other outbound calls, so it additionally supports the PRIVATE_KEY_JWT client authentication method and sends the configured federationRequestScopes. Note for existing deployments: outbound calls other than the fallback patient search previously always derived {fhirEndpointUrl}/.well-known/smart-configuration and ignored both configured URLs, so a server definition whose federationTokenUrl or authWellKnownConfigUrl points at a different token endpoint than that derived document will send its token requests to a different endpoint after upgrading. Review each existing System to System Data Exchange OIDC Server definition before upgrading and confirm that its configured authWellKnownConfigUrl points at the document you intend to use.

Spring LDAP has been updated to address CVE-2026-41720. An LDAP bind that supplies a distinguished name together with an empty password is now rejected before it reaches the directory server. User authentication in the LDAP Inbound Security Module is unaffected, as empty passwords were already rejected before reaching Spring LDAP. This does affect the module's system user connection: deployments that configure ldap.systemuser.dn while leaving ldap.systemuser.password blank will find that connection rejected, causing LDAP logins, user lookups, and group resolution to fail. Affected deployments should set a password for the system user, or clear ldap.systemuser.dn to connect to the directory anonymously.

Previously, requesting an access token from the SMART Outbound /oauth/token endpoint with grant_type=client_credentials and scope=offline_access (or online_access) returned a 200 response. Per RFC 6749 §4.4.3, those two scopes have no meaning in the context of a token request with grant client_credentials. The combination is now rejected at the token endpoint with HTTP 400 invalid_scope.

Previously, if a user account had the FHIR_EXTENDED_OPERATION_ON_ANY_INSTANCE permission assigned and authenticated via a SMART access token, the server would return an HTTP 500 Internal Server Error. This has been fixed.

Fixed a bug in App Gallery where the forgotten password flow would consistently fail with New password can not be more than 72 characters. regardless of how long the password actually was.

Previously, the $mdm-metrics admin endpoint returned 0 for goldenResources and sourceResources when MDM links existed across partitions and search_all_partition=true was configured. The endpoint now correctly honors partitioning. An optional partitionIds query parameter has also been added, allowing callers to restrict metrics generation to specific partition IDs.

Fixed a bug in System-to-System Data Exchange's token_endpoint selection strategy. Previously, the federationTokenUrl field on the OIDC Server definition was being ignored, in favour of the remote .well-known's token_endpoint value. Now, we use the federationTokenUrl first, and if it is absent, then fall back to checking the .well-known from the remote issuer. Furthermore, if smile is unable to determine a JWKS for a request, the returned exception has changed from InvalidTokenException to AuthenticationServiceException. InvalidTokenException is still thrown if the JWKS itself is either unparseable, or the issuer is untrusted.

Previously, the authWellKnownConfigUrl field on the OIDC Server definition was ignored during JWKS resolution, and the well-known URL was always assembled from the issuer. Now, when set, it is used exactly as configured (including any query string) to discover the jwks_uri. The JWKS source priority is unchanged: inline JWKS Text, JWKS File, JWKSet URL, configured well-known URL (new), and finally issuer-assembled well-known discovery.

Previously, the Java interceptor registered at the HL7V2IN_PRE_HL7V2_TO_FHIR_MAPPING_PROCESSING pointcut was not invoked when a JavaScript pre-conversion callback sets doNotAutoConvert = true. This has been fixed so that doNotAutoConvert flag now only controls whether Smile CDR's built-in HL7v2-to-FHIR mapping is executed, and does not affect user-defined Java interceptors registered at the PRE pointcut.

The CDS service now correctly processes order-dispatch hook requests. The dispatchedOrders context field is now read as an array of FHIR references (per the CDS Hooks specification) in addition to the legacy Bundle format. The optional fulfillmentTasks context field is now parsed and passed to the $r5.apply invocation under the fulfillmentTasks parameter, enabling fulfillment-aware CQL evaluation.

Processing an inbound HL7v2 ADT^A29 (Delete Person Information) message against a DSTU3 persistence endpoint failed with a HAPI-0529 error because the patient-deactivation bundle entry carried a PATCH verb, which DSTU3's Bundle.HTTPVerb does not define. For DSTU3 endpoints the entry is now a conditional-update PUT carrying a Patient resource with active=false; R4 and later endpoints continue to use PATCH with Parameters.

When an HL7v2 VXU message processed in DSTU3 mode supplies only a manufacturer name in RXA-17, Immunization.manufacturer is set to a Reference pointing at the contained Organization, matching the behaviour of the R4 and R5 mappers. Previously the contained Organization was added but Immunization.manufacturer was left unset.

Previously, MegaScale partition lookups and connection-pool initialization bound a hardcoded null partition, ignoring partitioning.default_partition_id=0. They now bind the configured default partition id, matching the underlying HAPI FHIR change.

Previously, paging through a FHIR Gateway response of Patient/$everything or Patient/[id]/$everything could return the same resource on more than one page; this has been corrected. A side effect of the fix is that the FHIR Gateway no longer relays referenced resources that a target server attaches to a search response on its own initiative; clients that want included resources must request them with _include or _revinclude. Searches that already use _include or _revinclude are unaffected.

Previously, a user authority configured with FHIR_READ_ALL_OF_TYPE, FHIR_WRITE_ALL_OF_TYPE, FHIR_DELETE_ALL_OF_TYPE, or FHIR_OP_INITIATE_BULK_DATA_EXPORT_GROUP whose argument was not a valid FHIR resource type (e.g. "Bad") caused every FHIR request made by that user to fail with an OperationOutcome containing the internal HAPI parameter name "theType must not be null". The misconfiguration is now reported with a clear, operator-actionable diagnostic that names the misconfigured permission and the offending argument.

Processing an inbound HL7v2 ADT^A29 (Delete Person Information) message against a DSTU3 persistence endpoint no longer fails with a HAPI-0541 error. The deactivate-patient bundle entry was missing a fullUrl, leaving the auto-generated MessageHeader.focus reference unresolvable.

The User Management page in the Admin UI now correctly enables the last-page navigation link. Previously, the user search query used a Slice (which does not count total results), so the pagination controls could not determine when the last page had been reached. The query now returns a Page with a total count, enabling all pagination links to reflect the correct state.

The ETL Importer and other script-runner callers no longer perform a database lookup on every processed row to determine whether a script is configured; the result is now cached and re-read only when scripts are reloaded. This removes a per-row database round-trip during large CSV imports.

For order-dispatch CDS hook requests, the resolved order resources referenced by dispatchedOrders are now passed as draftOrders parameters to the $r5.apply invocation. This ensures CQL evaluation has access to the full order resources when dispatchedOrders is provided as a string array.

Previously, requests from the Package Registry Swagger UI were rejected with 403 Forbidden response without prompting for authentication credentials. This has been fixed. Unauthenticated requests to protected paths now return HTTP 401 with a Basic authentication challenge prompting the user to enter credentials. Once the user enters valid credentials, the request is processed and the appropriate response is returned based on the user's permissions.

Failed rows processed by the ETL Importer (/bulk-import/process-etl-file/<moduleId>) are now recorded in the Transaction Log with outcome FAIL, including the filename, row number, and error message. Previously, rows that caused the JavaScript mapping script to throw an exception were silently dropped from the Transaction Log, making partial-import failures invisible to operators.

Under high-concurrency ingestion, MegaScale deployments that resolve references across shards (different databases) could deadlock — ingest threads would hold a connection in the source shard's pool while waiting indefinitely on the target shard's pool, eventually exhausting both. Concurrent cross-shard reference resolutions are now bounded by a new setting, MegaScale Cross-Partition Reference Concurrency, which defaults to db.connectionpool.maxtotal - 4 so each pool retains headroom for outer writes. A companion setting, MegaScale Cross-Partition Reference Acquire Timeout (seconds) (default 60), controls how long an ingest thread will wait for a permit before failing the write so the upstream consumer (Kafka, Camel, etc.) can redeliver. Two new metrics are also emitted on the FHIR Storage module — megascale_crossreference_queue_length (gauge of threads currently waiting on a permit) and megascale_crossreference_timeout_count (cumulative count of writes that failed to acquire a permit). Both are exposed via the cluster manager's metrics endpoints and via OpenTelemetry. See MegaScale: Cross-Partition Reference Concurrency for tuning guidance and observability details.

Previously, Smile CDR unconditionally appended sendStringParametersAsUnicode=false to Microsoft SQL Server JDBC URLs, which broke schema migration when the URL also set prepareMethod=none. This has been fixed in Smile CDR, which no longer produces that combination, and a URL that sets both explicitly is now rejected at startup. See String Parameter Encoding and Prepare Method for the supported settings.

In the CDA Exchange+ module, when exporting a CDA document, the child elements of the CD datatype were rendering in an invalid order. This has been fixed.

Previously, the default section narrative in CDA documents generated by the CDA Exchange+ module contained <div> elements, which would cause the documents to fail validation for some third-party validation tools. The output has been modified to ensure that only valid CDA Narrative tags are included.

In the CDA Exchange+ module, when exporting a document that includes Medication Activity entries, the child elements of <substanceAdministration> were being generated in an invalid order. This has been fixed.

When a row failed during an ETL Importer CSV import that was submitted without a file name, the failure entry in the Transaction Log displayed the file name as null. This has been fixed by displaying UNSPECIFIED when a user does not provide a file name.

Fixed an issue where a synchronous $mdm-clear request (using the Prefer: wait=N header) returned HTTP 500 on DSTU3 and R5 deployments. Synchronous $mdm-clear now returns a successful response on DSTU3, R4, and R5 deployments.

Fixed a bug where resources with a non-repeating identifier element (e.g. Composition, which has 0..1 cardinality on identifier) would cause a DataFormatException during $sdh.s2s.invoke-export ingestion if the resource already had an identifier populated. The identifier addition is now skipped for non-repeating identifier fields that are already populated, preserving the original identifier value.

Previously, the selections parameter of the order-select hook for CRD was missing the cpg-parameterDefinition extension. This could cause CQL evaluations to fail. The extension has been added to the first selections parameter.

When tokenization was enabled, a conditional create whose conditional URL used the FHIR-spec bare query form (e.g. identifier=http://system|value, without a leading ?) failed with an error such as HAPI-0929 or HAPI-0539, because the bare-form value was not tokenized before the match was evaluated. Such conditional URLs — including those emitted by HL7v2 ingestion — are now tokenized consistently with the full request-URL form.

The appSphere Developer Portal FHIR sandbox feature has been withdrawn following a security review, along with the sandbox OIDC client REST endpoints and the fhir.sandbox.url configuration item on the App Gallery module. The sandbox was the reason appSphere developers held OIDC client-management authority, so the OPENID_CONNECT_ADD_CLIENT, OPENID_CONNECT_EDIT_CLIENT, and UPDATE_USER permissions are no longer granted to the appSphere developer role, which can now follow least privilege. On upgrade, those permissions are revoked from already-provisioned self-registered appSphere developer accounts (those holding developer-portal access but not admin-console access), which retain their remaining developer-portal permissions.

Added audit logging to Forgot Password flow to be in compliance with HIPPA.

Previously, in MegaScale Patient ID Partition mode, writing a resource that referenced a non-Patient resource in a patient compartment by a client-assigned or UUID id failed because the reference target could not be resolved, even though it existed. Such references are now resolved correctly and the write succeeds.

Previously, the /openid-connect-servers endpoint returned the client secret in the response body for POST, PUT, and GET requests. The client secret is no longer returned as part of the response. Note that if a client secret is left blank on a PUT request, the secret is cleared from the respective database entry. This means configurations that currently read, modify, then update server configs should repopulate the client secret in the request body before sending a PUT request.

Previously, the Download Search Results button on the Audit Log (User Actions) page in the Web Admin Console failed with an HTTP 500 error. This has been fixed.

Previously, when the system_logs.only_on_error property was set to false, a successful transaction that captured no log lines had no SYSTEM_LOG step added. Now transactions with no log lines will contain a SYSTEM_LOG step, with the body No system logs captured for this request.

appSphere developers updating their own email address from the Developer Portal no longer require the global UPDATE_USER authority. The email update now runs as the system user internally and is restricted to the developer's own record and the email field only, so the developer role can follow least privilege and the UPDATE_USER permission no longer needs to be granted to it.

Fixed a potential race condition when two threads or cluster nodes simultaneously initialized the cluster cache synchronization entry for the same cache.

Previously, when System Log capture was enabled and Transaction Log events were stored in a Transaction Log Persistence module, processing a request that captured System Logs threw a NullPointerException when the resulting SYSTEM_LOG step was persisted. This has been fixed.

Previously, invoking Claim/$submit in the Prior Authorization Support (PAS) module with a Parameters body whose resource parameter could not be bound (e.g. a part not named resource) threw an unhandled NullPointerException and returned an HTTP 500 error. This operation now returns an HTTP 400 Bad Request with a descriptive error message instead.

Previously, submitting a self-registration request in the CDR Developer Portal (App Gallery) that failed validation would return an HTTP 500 error. Invalid registration now fails gracefully while providing failure feedback.

Previously, the Communication resources used to cache CRD responses when using the crdCacheGenerator Camel processor would not have a status set. These Communications will now have their status set to COMPLETED

Previously, in MegaScale Patient ID Partition mode, reviving a deleted resource with a client-assigned or UUID id failed with a HAPI-1326 error when the resource had ever been referenced from a resource on another shard. Reviving such a resource now succeeds. Genuinely deleted resources are still reported as gone.

A matched Patient returned by a custom match function with a bare (type-less) resource id is now type-qualified when building the group member entity reference and the persisted Consent's patient and performer references; previously the type-less Consent references caused the request to fail. The provider-access consent opt-out evaluation now also honors an active opt-out Consent for a member whose matched Patient carries a bare resource id; previously the type-less id never matched the stored Consent's type-qualified patient reference and the member was returned as matched despite having opted out.

Previously, a node running the Audit Log OpenTelemetry or Transaction Log OpenTelemetry module would fail to start if 'node.security.strict' was enabled. This has been fixed.

Previously, the MDM bundle match de-duplication mode in the HL7v2 inbound module would fail for some messages. The bundle update was rewriting references in conditional create queries, but not conditional update queries. The bundle update was also not handling http-escaped characters correctly. Both problems have been fixed.

Previously, on MegaScale deployments, a FHIR transaction Bundle could be rejected with Transaction Bundle contains circular dependencies on incompatible partitions even when no resources in the Bundle referenced each other in a cycle. This fix improves the circular dependency detection algorithm, so that such a Bundle is now accepted, while adding detection for indirect circular dependencies. A transaction Bundle is now rejected only when resources genuinely reference each other in a cycle, directly or indirectly, and are stored in partitions that cannot be written in a single database transaction. The rejection message was also updated to facilitate the identification of the Bundle.entry elements involved.

SmileHarness#getFhirClient() and SmileHarness#getSuperuserFhirClient() now return a client when the FHIR endpoint is a Hybrid Providers or FHIR Gateway module.

The Prior Authorization CRD module now correctly passes through arbitrary extension properties on CDS Hooks response cards (e.g. davinci-crd.associated-resource) back to the caller. Previously, extension properties returned by the Camel route were silently discarded during deserialization.

Previously, the AG_OAUTH2_CLIENT_SECRET_REGENERATED interceptor pointcut received only the generated client secret, with no context about the application it belonged to. The pointcut now also receives that application as an AGPortalJson. If an interceptor on this pointcut throws, the generated secret remains valid and the generate-secret response carries a warning of INTERCEPTOR_NOTIFICATION_FAILED.

Previously, the $provider-member-match operation required Consent.policy.uri to be present and set to a valid HRex consent policy value (#sensitive or #regular). This requirement comes from the HRex Consent profile, but the PDex Provider Consent profile used by $provider-member-match treats both Consent.policy and Consent.policy.uri as optional. Members were incorrectly placed in the ConsentConstrainedMembers group even when all other matching validations passed. The default consent policy validation is now skipped for $provider-member-match operations, aligning with the PDex Provider Consent profile. The existing HRex consent policy validation remains unchanged for $member-match and $bulk-member-match operations. Custom consent validation scripts, if configured, continue to take precedence for all operation types.

Previously, a LiveBundle rule configured to track a reference shared across partitions could fail to find matching resources when the shared resource lived in a different partition than the caller. This has been fixed.

Fixed a bug in Prior Auth CRD where the Order Select request failed with a 500 Internal Server Error when the DraftOrders bundle contained orders not included in the selection. The server now processes only the selected orders and uses non-selected orders in the DraftOrders bundle as additional context.

Previously, module configuration items that load a file resource failed module startup with a URI is not hierarchical error if the value was a relative file: URI such as file:customerlib/users.json. Relative file: URIs now resolve against the Smile CDR working directory again, as they did prior to 2026.08.

Claim/$submit now stores the PASRequestBundle only after the Camel route completes successfully. If the route throws an error, neither the PASRequestBundle nor the PASResponseBundle is persisted, and the error is returned to the client so the provider can resend a corrected bundle.

Module config #{...} placeholders are now evaluated with a restricted SpEL context.

Previously, configuration items that were loaded as resources (such as seeded OIDC Clients/Servers) could refer to a URL to load the resource from. This has been removed, and only resources on the classpath, or files on disk can be referred to this way.

Changes have been made to the Password Reset Flow of the Local Security module. Each password reset token may be used precisely once. If an invalid code is entered, the existing token is invalidated and a new password reset must be requested. Furthermore, the token now has an expiry time of one(1) hour, instead of 24 hours.

The URL-scheme restriction introduced in #8682 (which prevents seeded resources from referencing remote URLs) now also applies to child module contexts. Previously, module-level Spring contexts did not inherit the parent context's SafeResourceEditorBeanFactoryPostProcessor, so a remote URL supplied via a module-scoped config property would be accepted. Only classpath and filesystem resources are now permitted in all contexts.

Previously, LiveBundle operations that resolve a specific subscriber, resource, or tracking ID resolved LiveBundle data across all partitions instead of the caller's own. These lookups are now scoped to the caller's partition.

Improved the consistency of permission enforcement for the server-level $expunge operation.

The FHIR_OP_INITIATE_BULK_DATA_IMPORT permission is no longer implicitly granted through SMART authorization.

Patched code that could've been vulnerable to XXE injection.

Previously, the OpenID Connect token endpoint re-fetched a client's key set from its configured JWKS Url on every client-authentication request. The key set is now cached, and a key rotation at that URL is picked up without waiting for the cache to expire. Where a JWKS Url is configured, it is the only key source used for that client: any Public JWKS Keystore on the same client definition is ignored. The new OIDC HTTP Client: JWKS Fetch Failure Cache (secs) setting controls how long a failed fetch is remembered.

Updated CdrAuthorizationInterceptor to omit Group and List resources if requesting user only has permissions on TYPE for patient compartment.

Previously, LiveBundle operations that query LiveBundle data based on group or watchlist tokens were not scoped to the caller's partition and could return data from other partitions. These lookups are now scoped to the caller's partition.

The console colour library used by the CLI and the server control client has been migrated from the deprecated org.fusesource.jansi:jansi to its maintained successor, org.jline:jansi, resolving CVE-2026-8484.

Logback has been upgraded from 1.5.25 to 1.6.3 to support the replacement Jansi library: the console colour configuration now uses logback's JansiConsoleAppender, which the 1.5 line does not provide. The shipped logback.xml sets logback.skipCallerContradictionAnalysis to suppress a false-positive warning new in logback 1.6; customized logging configurations may need the same setting.

CrdToCqlRequestProcessor no longer falls back to resolving the payer Patient by matching a member identifier on the prefetched Coverage resource. payerPatientId must now always be supplied in the Prior Auth CRD context.

Smile CDR 2026.05.R02 (Synchronicity)

 

Release Information

Released 2026-07-22
Codename Synchronicity
HAPI FHIR Smile CDR 2026.05.R02 is based on HAPI FHIR 8.10.1, and includes all changes and fixes included in this version. Please see the HAPI FHIR ChangeLog for details about what has changed.

Upgrade Instructions

GraalVM Javascript Execution Changes

Two large breaking changes are included in this release.

  • Arbitrary Java types may no longer be instantiated by scripts. For those requiring the ability to invoke specific Java types (e.g. let MyType = Java.type('com.example.MyType');) must now manually allowlist the fully-qualified class names desired, via the class_allowlist property. Warning: allowlisting classes that expose host capabilities (e.g. java.lang.Runtime, java.lang.ProcessBuilder, java.lang.System, java.io.File, java.net.URLClassLoader, javax.script.ScriptEngineManager) effectively re-enables the sandbox escape this release fixes. Allowlist only the classes your scripts strictly need.
  • The ability to perform actions such as importing JS modules, or other disk-reading operations has been limited so that access is only provided to the customerlib/ directory.

MDM Expansion Breaking Change for MongoDB Users

This release introduces support for MDM expansion with search and $everything operation when PatientId partitioning mode is enabled (GL8366). However, this change breaks some MDM features when using MongoDB as the persistence layer.

Breaking Changes for MongoDB

The following MDM features are no longer functional:

  • MDM expansion on Search operations
  • MDM expansion on $everything operations
  • Over Inclusion on $everything operations

These features remain fully operational when using any supported RDBMS (PostgreSQL, SQL Server, Oracle, MySQL).

No Fix Planned

Due to the upcoming sunset of MongoDB support and the absence of clients running MongoDB with the MDM module in production environments, these broken features will not be fixed.

Camel Dependency Upgrade

We have upgraded our Camel dependency version from 4.10.x to 4.18.x. As a result, kebab-case is no longer supported in Camel routes.yaml files. Please ensure camel case is used instead.

Changes

Backported from: 2026.08.R01

Previously, the /openid-connect-servers endpoint returned the client secret in the response body for POST, PUT, and GET requests. The client secret is no longer returned as part of the response. Note that if a client secret is left blank on a PUT request, the secret is cleared from the respective database entry. This means configurations that currently read, modify, then update server configs should repopulate the client secret in the request body before sending a PUT request.

Smile CDR 2026.05.R01 (Synchronicity)

 

Release Information

Released 2026-05-21
Codename Synchronicity
HAPI FHIR Smile CDR 2026.05.R01 is based on HAPI FHIR 8.10.0, and includes all changes and fixes included in this version. Please see the HAPI FHIR ChangeLog for details about what has changed.

Upgrade Instructions

GraalVM Javascript Execution Changes

Two large breaking changes are included in this release.

  • Arbitrary Java types may no longer be instantiated by scripts. For those requiring the ability to invoke specific Java types (e.g. let MyType = Java.type('com.example.MyType');) must now manually allowlist the fully-qualified class names desired, via the class_allowlist property. Warning: allowlisting classes that expose host capabilities (e.g. java.lang.Runtime, java.lang.ProcessBuilder, java.lang.System, java.io.File, java.net.URLClassLoader, javax.script.ScriptEngineManager) effectively re-enables the sandbox escape this release fixes. Allowlist only the classes your scripts strictly need.
  • The ability to perform actions such as importing JS modules, or other disk-reading operations has been limited so that access is only provided to the customerlib/ and scripts/ directories.

MDM Expansion Breaking Change for MongoDB Users

This release introduces support for MDM expansion with search and $everything operation when PatientId partitioning mode is enabled (GL8366). However, this change breaks some MDM features when using MongoDB as the persistence layer.

Breaking Changes for MongoDB

The following MDM features are no longer functional:

  • MDM expansion on Search operations
  • MDM expansion on $everything operations
  • Over Inclusion on $everything operations

These features remain fully operational when using any supported RDBMS (PostgreSQL, SQL Server, Oracle, MySQL).

No Fix Planned

Due to the upcoming sunset of MongoDB support and the absence of clients running MongoDB with the MDM module in production environments, these broken features will not be fixed.

Camel Dependency Upgrade

We have upgraded our Camel dependency version from 4.10.x to 4.18.x. As a result, kebab-case is no longer supported in Camel routes.yaml files. Please ensure camel case is used instead.

Changes

The FHIR Gateway module now supports proxying the $validate-code, $lookup, $translate, and $validate operations (both type-level and instance-level) to configured backend targets using the existing operationRoutes mechanism. Previously these operations were not recognized by the Gateway's resource provider and requests would fail to route. Parameters bodies submitted via POST are forwarded to the target server, enabling terminology and validation workflows to be routed through the Gateway.

The CDA Exchange+ module will attempt to infer resource authorship by cascading author data from ancestor nodes in the CDA document when no local author element is present in the entry being processed.

The MDM matching architecture now supports custom matching and similarity algorithms. Users can implement and deploy their own matching logic via customer JARs. See Custom MDM Matching Algorithms for details.

Added JWKSet URL support to JWK validation for OIDC servers. When the JWK set is configured in multiple places, the validation priority is: inline JWKS Text, JWKS File, JWKSet URL, and finally issuer .well-known/openid-configuration discovery.

The Transaction Log Broker module can now send messages using buffered flushes instead of a single-threaded executor. This significantly improves throughput under high concurrency, especially when message broker latency is non-trivial. See the Transaction Log Broker documentation for more details.

Added new permissions for controlling access to Smile Portal applications.

  • SMILE_PORTAL_ALL - Grants access to all Smile Portal applications
  • SMILE_PORTAL_OF_TYPE - Grants access to specific Smile Portal application types (e.g., PRIOR_AUTH, PAYER_TO_PAYER, PATIENT_MANAGEMENT, TERMINOLOGY)

For Prior Auth CRD module, The CrdApplyProcessorConfig now supports optional authorization headers for the data endpoint used in CQL $r5.apply requests. A new dataEndpointAuthorizationHeader configuration option has been added to allow secure access to clinical data repositories. Additionally, the clinicalRepositoryBaseFhirEndpoint configuration is now optional, and a new useServerData parameter can be set to control whether server data should be used in $r5.apply requests.

The System Config endpoint now includes comprehensive database statistics in the exported zip file. This feature collects database metadata, connection pool statistics, and performance metrics from all modules with datasources. See System Config Endpoint for more information.

MDM expansion on search and $everything operations is now supported when using PatientId partitioning mode. Note: This functionality is not available when using MongoDB as the persistence layer.

The Camel HTTP Endpoint allows users to invoke Camel routes via HTTP calls. See the documentation for details.

Smile Portal Web Admin Console apps (e.g. User Management, Module Config) are now shown or hidden based on the permissions granted by the user's assigned Role.

Two new Smile Camel processors have been added for terminology operations. The codeSystemLookupProcessor performs the FHIR CodeSystem $lookup operation, and the conceptMapTranslateProcessor performs the FHIR ConceptMap $translate operation. These processors can be used in Camel routes via the smile: URI scheme. See the Smile FHIR Storage Processors Page for more details.

The HL7 v2.x Inbound module now supports the QBP^Q23 (Get Corresponding Identifiers) query transaction. This implementation conforms to the IHE PIX Query ITI-9 profile specification. See Inbound: Query Processing for details.

When the CDA Exchange+ module cascades authorship data within a document being imported, the FHIR elements inherited from an ancestor resource may include data types that are not valid for the target field. These invalid elements will be filtered out before populating the field, to ensure that the generated resources are valid.

When the CDA Exchange+ module cascades authorship data within a document being imported, if the target field has a bounded maximum cardinality, the collection of authors will be truncated to the target size. References to Practitioner or PractitionerRole will be prioritized over references to non-human agents such as Device or Organization. Otherwise, the elements will be selected in the order that they occur in the source CDA document.

Added new AppSphere roles and permissions to Smile Portal. The AppSphere module now exposes three separate application types (Admin Console, Developer Portal, and Application Gallery), each with dedicated roles. These roles control access to the corresponding AppSphere components within Smile Portal.

Transaction logs now support configurable capture of HTTP request and response headers. Two new module settings, transactionlog.request_headers_to_store and transactionlog.response_headers_to_store, control which headers are extracted and stored in the additionalJson field of transaction log entries. Response headers default to capturing Content-Location, enabling tracing of async FHIR operations (e.g. $export).

Added new MDM UI roles and permissions to Smile Portal. The MDM-related modules (MDM, MDM Dashboard, and MDM Comparison) are now exposed as a single MDM UI application type with dedicated roles. These roles control access to MDM functionality within Smile Portal.

The system role is bypassing consent checks when consent enforcement is enabled. Internal consent resource lookup for consent checking now runs with the system role via Roles.runAsSystem(). Other internal processes requiring interaction with DAOs will also need to be updated with the same approach.

Kafka users running batch jobs with long running steps could exceed the Kafka max.poll.interval.ms timeout and trigger a rebalance. This would result in stuck jobs or duplicate results in $export. A fix has been implemented in order to detect long-running jobs and avoid this double processing / Kafka rebalance issue. However, the best remediation is still for users to increase the max.poll.interval.ms setting of Kafka if they notice rebalance or duplicate delivery logs/errors. Rebalancing is an expensive process that will slow processing, and could cause other disruptions on the system. NB: This feature is not supported for Mongo backed persistence layers.

A new REST endpoint GET /transaction-log/event-codes has been added to the admin-json API. It returns the complete list of valid Transaction Log event type and subtype codes along with their human-readable descriptions, making it easier for API consumers to discover and display available filter values without consulting source code or documentation.

The Transaction Log REST API response now includes a totalRecords field that reports the total number of records matching the query. This enables API consumers to display pagination information such as total page count and result counts.

The FHIRGW_GET_TARGET_PREINVOKE pointcut now supports adding custom HTTP headers to outgoing GET requests made by the FHIR Gateway. Interceptors can call addAdditionalHeader() on the GetRequest parameter to inject headers such as authorization tokens, which are then applied when the gateway downloads bulk-exported NDJSON files via $proxy-link operations.

When the $invoke-export operation is initiated, the associated transaction log event sub type now displays the code FHIR_OPERATION_INVOKE_EXPORT and can now be allow-listed.

Added a new FHIR Endpoint admin role to Smile Portal. Users assigned the FHIR_ENDPOINT_ADMIN role are granted access to the FHIR Endpoint application within Smile Portal along with FHIR superuser permissions.

The Smile Portal custom external application configuration now supports an optional description field, allowing administrators to provide a human-readable description for each custom application. The external application labels and group names in examples and documentation have been updated to use clearer naming (e.g. 'Custom Applications FHIR Endpoint').

When installing an NPM package through the Package Registry module, adding the header Prefer: respond-async to the call will start an asynchronous batch job to process the package and its dependencies.

The Admin JSON API now includes several new endpoints for audit and transaction logs. New GET /audit-log/modules and GET /transaction-log/modules endpoints return the list of available module IDs. A new GET /audit-log/event-types endpoint returns available audit event type codes with human-readable descriptions. A new GET /audit-log/export endpoint exports audit events as a CSV file in a ZIP archive. The audit log response now includes a totalRecords field for pagination support, and both audit and transaction log endpoints now support additional search filter parameters.

The $sdh.update-tokenization job can now optionally be configured to update (add/remove) tokenization to all versions of resources, not just the current version.

The $bulk-member-match and $sdh.s2s.bulk-member-match operations on the Group resource now produce FHIR_OPERATION_BULK_MEMBER_MATCH in the Transaction Log instead of FHIR_OPERATION_UNCLASSIFIED, enabling accurate filtering and auditing of bulk member match activity.

$davinci-data-export operation now generates transaction log event type FHIR_OPERATION_DAVINCI_DATA_EXPORT & audit event type FHIR_OP_DAVINCI_DATA_EXPORT when it has been invoked.

The $mdm-clear operation now supports synchronous execution via the Prefer: wait=n request header, where n is the number of seconds the client is willing to wait. When specified, the operation deletes MDM links and golden resources directly (bypassing Batch2) and returns a 200 response with a resourcesCleared count. If the total number of MDM links exceeds 10,000, the operation rejects the request with a 422 error and instructs the caller to resubmit without the Prefer: wait=n header to run asynchronously. Omitting the header preserves the existing asynchronous Batch2 behavior.

Added $provider-member-match operation on the Group resource for provider-initiated member matching. These operations produce distinct transaction log event subtypes (FHIR_OPERATION_PROVIDER_MEMBER_MATCH and BATCH_JOB_PROVIDER_MEMBER_MATCH) and audit event type FHIR_OP_PROVIDER_MEMBER_MATCH, enabling them to be distinguished from payer-to-payer $bulk-member-match in transaction logs and audit trails.

Smile Portal now supports FHIRWeb as a distinct application type with a dedicated FHIR_WEB_ADMIN role.

Added a preview missing-translation suggestion pipeline: codes that in-place translation cannot map via ConceptMap $translate can be dispatched asynchronously through a FHIR Task to a configured provider that suggests candidate codings. Gated by inplace_translate.missing_translation_suggestion.enabled; the active provider is selected via missing_translation_suggestion.provider.active_name. Disabled by default, in which case no Task is created and no Subscription is registered.

Added two activation methods for In-Place Code Translation: automatic translation of every stored Observation via module configuration, and a Camel processor for route-based translation.

Added in-place code translation: Observation.code can be translated to LOINC using the ConceptMap $translate operation, adding the translated coding alongside the original before the resource is stored. See In-Place Code Translation for details.

Added asynchronous Task coordination for the missing-translation suggestion pipeline: unmapped codes are deduplicated into a FHIR Task, matched by a channel-based Subscription, and resolved by a configured suggestion provider whose candidates are written back onto the Task.

The Admin JSON API now includes a new GET /transaction-log/endpoints endpoint that returns the list of available endpoints (node ID and module ID pairs) for filtering transaction log entries.

The $provider-member-match operation now evaluates Consent opt-out status for each matched member. If an active Consent resource with category provider-access and a deny provision covering the current time is found for a matched member, that member is placed in the ConsentConstrainedMembers group instead of the MatchedMembers group. If no matching Consent is found, the member is assumed to be opted in. The $bulk-member-match operation is unaffected and retains its existing behavior. Additionally, the $provider-member-match response groups now use the pdex-provider-member-match profile for the match group and include Coverage resources in contained resources with a base-ext-match-coverage extension on each group member.

Added a new Cluster Manager configuration property (ag.interceptors.expose_oidc_client_secret) that, when enabled, includes the OIDC client secret in the AGConsoleJson passed to AG_APPLICATION_STATUS_UPDATING and AG_APPLICATION_STATUS_UPDATED interceptor pointcuts.

A new Delta Lake Export module (REALTIME_EXPORT_DELTA_LAKE) is now available as an Early Access feature. It extends Realtime Export to stream FHIR resource changes to Delta Lake tables via a customer-managed Spark Connect server, enabling customers on data lake architectures (Databricks, Spark, cloud object stores) to receive FHIR data without building custom ETL pipelines. See the documentation for details.

The FHIR Gateway's $everything operation on Patient and Encounter now honours the _type query parameter. Previously, _type was silently dropped before the request reached the target FHIR server, causing the operation to return all resource types regardless of the filter. Both instance-level (/Patient/<id>/$everything?_type=..., /Encounter/<id>/$everything?_type=...) and type-level (/Patient/$everything?_type=..., /Encounter/$everything?_type=...) endpoints are supported. Multi-value filters accept either comma-delimited (?_type=Patient,Observation) or repeated (?_type=Patient&_type=Observation) URL forms; the gateway forwards both as a single comma-delimited _type parameter to the target server.

Two new configuration properties have been added to the Persistence module to control ValueSet $expand operation result sizes:

  • dao_config.expansion.pre_expand_default_count - Controls the default number of codes returned by $expand when no count parameter is specified
  • dao_config.expansion.pre_expand_max_count - Controls the maximum number of codes that can be returned by $expand
Previously these values were not configurable, causing $expand to always use HAPI's hardcoded default of 1000 codes.

Enhanced performance for patient linkage in $sdh.s2s.invoke-export operation. Get Patient from Task creation instead of fetching it downstream each time in DocumentReference service.

Improved performance of HL7 v2.x message ingestion by avoiding deep cloning the original HL7 v2.x message on every call. A new getOriginalMessageReadOnly() method provides direct access to the original message for read-only operations.

In the 2025.05 release, Kafka producers were changed to flush after every send (autoFlush=true). This narrowed the message-loss window before broker acknowledgement, but disabled Kafka's producer-side batching, reducing throughput on high-volume workloads. This behaviour can now be configured using the new kafka.producer.auto_flush property (default: true). See the Message Broker: Kafka page for trade-offs and tuning guidance.

A performance bottleneck in the Camel module when writing to the transaction log has been removed.

The INLINE_NUMERIC value of the db.sql_parameter_bind_mode configuration property is now deprecated. Hibernate's CRITERIA_VALUE_HANDLING_MODE only supports INLINE or BIND, so INLINE_NUMERIC had no distinct effect and was treated as NEVER_INLINE.

Prior Authorization modules (PAS/CRD) now handle Camel route exceptions more consistently, propagating FHIR exceptions directly to clients while wrapping unexpected errors. Documentation added for error handling best practices in custom Prior Auth Camel routes.

Previously, PAS and CRD modules were only able to support parsing string and actual resource at the end of camel exchange. Now, those modules can also parse stream at the end of camel exchange. Also, renamed pasSubmitProcessor to createPendedPASResponseProcessor.

Updates the $sdh.s2s.invoke-export operation to accept an optional new parameter: sourcePatientID. When provided, the operation will skip the member match step, and use the pre-matched patient for the export. This also means the memberMatch parameter is now optional, provided one of sourcePatientID or MemberMatch is present.

The DaVinci CRD and PAS Camel route entry points have been renamed to direct:start-crd and direct:start-pas-submit respectively. Previously, both routes used the generic direct:start URI.

CDS hook services registered via PriorAuthCRD module now supports configuration to include arbitrary extension properties in their hook definition files. Note: the davinci-crd.configuration-options extension is no longer injected automatically & implementations who wish to include it must add it explicitly to their CDS hook service JSON configuration.

For PriorAuth CRD Module, The DaVinci CRD max-cards and coverage-info extension handling has been moved out of the cqlToCrdResponseProcessor Camel processor into two new standalone processors: daVinciMaxCardsProcessor and daVinciCoverageInfoProcessor. These must now be explicitly added to CRD Camel routes after cqlToCrdResponseProcessor to apply card limiting and coverage-info filtering. Previously, these extensions were hard-coded and automatically applied within cqlToCrdResponseProcessor; that implicit behaviour has been removed.

GraalVM Javascript execution environments may no longer read files from disk arbitrarily. Only files in customerlib/ or scripts/ directory may be read from the JSEE.

GraalVM Javascript execution environments may no longer instantiate arbitrary Java types. Instead, any Java types that scripts need to instantiate must be manually allow-listed via the new class_allowlist property

Previously, the Terms of Service agreement page (/signin-tos) could return an HTTP 500 error when a user submitted the agree form after their authentication session had already expired (for example, by agreeing from another browser tab). The endpoint now redirects to the sign-in page when no active authentication is present.

The "Boot cycle detected" error message now includes the names of the modules that form the dependency cycle, making it easier to diagnose and resolve circular module configuration issues.

Previously, accessing extra components on composite HL7v2 field types (such as PL and CE) in the JavaScript execution environment was not supported and would fail. This has been fixed: composite HL7v2 types now support extra component access, consistent with primitive types.

Previously, the "TLS: Disable SNI checking for debugging" setting had no effect on outbound client connections. When the destination hostname did not match the server certificate (e.g. connecting via IP address instead of hostname), the connection would fail with a certificate mismatch error even with the setting enabled. The setting now correctly bypasses hostname verification for all outbound connections that use a custom TLS configuration, including HL7 v2.x over HTTP and outbound OAuth2/SMART authentication requests.

The default REST-hook endpoint URL validation regex has been corrected. Previously, the regex incorrectly allowed URLs with invalid schemes such as htt:// because the p in http was marked as optional. The regex now correctly requires URLs to begin with http:// or https://.

When operating MegaScale in Patient ID Partition Mode with Auto-Create Placeholder Reference Targets enabled, auto-creation of an Ancillary Resource resulting from the creation of a Patient Compartment Resource resulted in a failure. This has been corrected.

Previously, the outbound HL7 v2 mapper incorrectly populated IN1-13 (Plan Expiration Date) with the Coverage period start date instead of the period end date. In addition, NK1-9 (End Date) was silently populating NK1-8 a second time instead of being populated from the patient contact period end. Both issues have been corrected so that IN1-13 and NK1-9 are now populated from the corresponding end elements. This only affects outbound HL7 v2 messages and does not require any data migration.

Users with MODULE_ADMIN_FOR_MODULE permission for specific modules could not access those modules in the Web Admin Console despite having proper permissions. This has been fixed.

Previously, in MegaScale PATIENT_ID partition mode, performing a FHIR Patch on a Patient resource by identifier within a transaction bundle returned a 400 error (HAPI-2616). This has been fixed.

Previously, setting the password encoding scheme to any PBKDF2 option would cause user password updates to fail. This would exhibit in the Web Admin Console as though nothing had occurred, and in the logs, there would be a DataIntegrityViolationException. This has been fixed. Also, a new stronger option, PBKDF2_256_310000_RND, has been added and is the recommended choice for new deployments.

Fixed the JavaScript documentation for adding contained resources without the TransactionBuilder API. The '#' prefix for contained resource references was incorrectly placed on the resource id instead of on the reference element.

Previously, built-in SearchParameters required for system operation (Basic:*, Subscription:*, SearchParameter:*, and *:url) could be inadvertently retired by configuring broad SearchParameter disable patterns (e.g. disable_patterns=*) or by narrowly scoped enable patterns that excluded them. This could cause the Subscription module and terminology services to fail at startup. This has been fixed. See SearchParameter Tuning Patterns for more details.

Previously, when tokenization was enabled, chained searching (e.g. finding Observations by a Patient's identifier) would return no results even when matching data existed. This has been fixed.

Previously, re-creating a deleted resource would raise an exception when the system operates in PatientID partitioning mode. This issue has been fixed.

Previously, PriorAuth CRD module would fail to start when CDA Exchange+ module was also configured. This behaviour has been fixed.

Previously, when processing an appointment-book CDS Hook request, the Prior Authorization Coverage Requirement Discovery (CRD) Module would map the appointments context value incorrectly to a Parameter named draftOrders. This has been fixed and it is now correctly mapped to a Parameter named appointments

Prevent commons-logging from being transitively included on the runtime classpath. spring-jcl (from spring-core) and jcl-over-slf4j already provide the commons-logging API.

The $mdm-link-history operation operation was throwing a NullPointerException when used in conjunction with Patient ID Partition Mode. This has been fixed

When exporting CDA documents through the CDA Exchange+ module, assignedAuthor elements were being rendered with multiple ID's. This issue has been fixed by making sure the appropriate caches are being cleared between elements.

Previously, FHIR Gateway pagination could return duplicate or missing resources when used with MegaScale targets and interceptors which perform identifier expansion. The pagination processor now correctly uses the SELF link returned by the target response bundle, which reflects interceptor modifications such as identifier expansion, preventing incorrect page link generation.

Previously, modifications to the pattern properties for enabling and disabling search parameters would be ignored in specific scenarios. This issue is resolved. Follow the link to access documentation regarding enable/disable patterns for SearchParameters.

When a tokenization rule's status was set to DISABLED after running detokenization, the TokenizationSearchInterceptor still tokenized search parameter values, causing searches to return no results. The fix filters DISABLED rules from the search interceptor's rule map, aligning search behavior with the existing write-side filtering.

Update documentation on P2P, Prior Authorization and Provider Access

Previously, the Consent hook CONSENT_BUILD_FIXED_STATIC_POLICY was declared using ConsentParameterizedPolicyRequest instead of ConsentFixedPolicyRequest. This has been fixed.

Previously, subscription system processes (activation, matching, registration, async delivery, and SearchParameter cache refresh) were bypassing consent to avoid failures in consent interceptors due to missing authentication using a flag in RequestDetails#userData. The fix has been updated to instead run these processes as a system user in order to enable them to bypass consent.

Previously, initialization system processes (validation support, search parameter, tokenization and MDM subscription), as well as async system processes (MDM message handling, HL7v2 inbound/outbound message processing, validation resource fetching) ran without a security context. These processes now run with an authenticated ROLE_SYSTEM principal, ensuring consent and security interceptors can properly evaluate authorization.

Previously on the Smile CDR documentation site, search results in the left sidebar were being clipped at the bottom of the sidebar and the last entries could not be scrolled into view. This has been fixed and the results list now fits within the visible area and is fully scrollable.

Previously, the FHIR_ALL_DELETE permission did not apply query filter restrictions when processing delete requests. Users granted the FHIR_ALL_DELETE permission with a query parameter filter (e.g. ?category=vital-signs) could delete resources that did not match the filter. This has been fixed.

Previously, searching for a Patient by identifier in MegaScale PATIENT_ID or BUCKETED_PATIENT_ID partition mode would return a 400 error when the identifier system matched a pre-resolvable patient identifier system, but no Patient existed with that identifier system. This has been fixed so that the search now correctly returns an empty Bundle.

Previously, HL7v2 inbound message processing could fail with a HAPI-2223: Partition IDs have not been set error in MegaScale PATIENT_ID mode when the storage_tenant_name property was left blank. This issue has been fixed.

The FHIR Gateway $proxy-link operation now correctly includes HTTP Basic authentication credentials when downloading bulk export files from a target server. Previously, GET requests issued by the gateway did not attach configured HTTP Basic credentials, causing bulk export file downloads to fail with a 401 Unauthorized error when the target required authentication.

Previously, when request validation was enabled and Implementation Guide profiles were installed, Bundle resources could produce spurious REFERENCE_REF_CANTMATCHCHOICE validation errors. This was caused by a missing isSuppressMessageId delegation in the validator policy advisor, which has been corrected.

Previously, the Subscription Submitter was ignoring the scheduled_tasks.async_persisted_resource_processing.processing_interval property, potentially causing Subscription latency by using a hardcoded default interval (5000ms) instead of the user-defined configuration value. This has been fixed.

Previously, when using MegaScale Patient ID partitioning mode, conditional PATCH and DELETE operations using a patient identifier (e.g., Patient?identifier=Patient|123) would create a phantom UUID mapping if the patient did not already exist. This has been fixed.

Previously, when using MegaScale Patient ID partitioning mode, a conditional DELETE on a non-existent patient would return a confusing diagnostic message referencing a system-generated UUID. The response now returns a clear message indicating that no resource matching the requested URL was found.

Warning messages in the view detail panel of batch jobs was no longer present during regression testing. I've fixed this by re-introducing the html field with its corresponding binding.

Previously, performance tracing interceptors could add large HTTP response headers, causing HTTP 431 "Response Header Fields Too Large" errors for requests with many or complex trace entries (e.g. large identifier resolution queries). Individual trace header values are now truncated to approximately 4KB, and the cumulative size of all trace headers on a single response is capped at 7KB (leaving headroom for standard response headers), to prevent this error.

Previously, the System to System data exchange batch job for $invoke-export could fail with an exception when retrieving the member id. The member id is now properly passed through the batch job steps.

Three FHIR Gateway interceptor defects affecting bulk export operations have been corrected. First, the FHIRGW_OPERATION_TARGET_PREINVOKE pointcut was not being broadcast for bulk export operations ($export, $davinci-data-export, $export-poll-status); interceptors registered for this pointcut are now invoked correctly before the request is forwarded to the target. Second, the FHIRGW_GET_TARGET_PREINVOKE pointcut fired after gateway-generated headers were assembled, so interceptor mutations to request headers arrived too late to affect outbound GET requests; the pointcut now fires first, ensuring header modifications (such as credential swaps) are applied. Third, duplicate HTTP headers (for example, duplicate Authorization headers) could appear on outbound GET requests when both the gateway-generated headers and an interceptor supplied the same header name; the interceptor-supplied value now wins. In particular, an Authorization header set by a FHIRGW_GET_TARGET_PREINVOKE interceptor now takes precedence over the gateway target's configured HTTP Basic credentials, so interceptors can reliably swap outbound credentials.

Previously, the $member-match operation could fail with a HAPI-0464 error when the CoverageToMatch resource did not include an id field. The missing id caused an unfiltered Coverage search that could fail on large datasets. The operation now correctly skips the id-based search and falls through to identifier-based matching when no Coverage id is provided.

Previously, in the PriorAuth CRD module, using a CDS Hook request inside the JavaScript API would result in incomplete serialization of the prefetch property. This has been fixed.

In the FHIR Gateway module, two issues with operation forwarding have been fixed:

  • POST /[ResourceType]/$validate with a raw resource body (instead of a wrapped Parameters resource) was returning a 400 error.
  • GET requests for operations such as $validate-code and $lookup that supplied parameters as URL query parameters were returning a 400 error.

In the HTTP Camel Endpoint module, the Content-Length header of the response was not always accurate. This has been fixed.

Previously, the Camel HTTP endpoint module was not making use of the context path configuration parameter. This has been fixed. If the request URL does not begin with the configured context path, the endpoint will return a 404 Not Found response code. Only the portion of the request URL to the right of the context path will be used to match with the configured mappings.

Previously, the profile for no-match group for $provider-member-match operation was incorrectly set. This has now been fixed to http://hl7.org/fhir/us/davinci-pdex/StructureDefinition/pdex-provider-member-no-match.

Fix #null references in $provider-member-match response groups. When member Patient resources in the request payload have no id , the response was producing invalid #null references in the extension and a missing member.entity.reference on the affected group members

Previously, in MegaScale environments with cross_partition_reference_mode=ALLOWED_UNQUALIFIED, searches involving references to resources in non-default partitions returned empty results. This is now fixed.

Fixed duplicate entries in the Web Admin documentation sidebar and search. Previously, every page under the Configuration Categories chapter (from Web Admin Console Settings through User Self Registration) was listed twice. Each configuration category page now appears exactly once.

Previously, the Terms of Service agreement page could return an error when the OAuth2 client session was no longer available at the time the user submitted their agreement (for example, when opened in another tab). The endpoint now redirects to the sign-in page in this scenario.

Previously, $graphql queries against partitioned resources in MegaScale REQUEST_TENANT mode could fail with 'Unable to execute GraphQL Expression'. This has been fixed so that GraphQL requests now resolve to the requested tenant's partition correctly.

Fix parameter validation for the $log-questionnaire-errors operation under the Prior Auth Support module.

Fixed a broken module link in the transaction log column on the Web Admin Console OpenID Connect Clients and Servers pages. Clicking the module link now correctly navigates to the module's runtime status page instead of returning a 404.

Fixed an issue with the $sdh.bootstrap-rte batch job where resources with client assigned (non-numeric) ids would not be exported (even though the job would incorrectly state that they were).

The payer_organization_reference configuration property has been removed from the Prior Auth Support (PAS) module. This property was previously used to identify the intermediary system's Organization resource but was no longer in use. Existing module configurations containing this property will no longer recognize it.

Smile CDR 2026.02.R01 (Prologue)

 

Release Information

Released 2026-02-19
Codename Prologue
HAPI FHIR Smile CDR 2026.02.R01 is based on HAPI FHIR 8.8.0, and includes all changes and fixes included in this version. Please see the HAPI FHIR ChangeLog for details about what has changed.

Upgrade Instructions

Upgrade Notes

Major Database Change Breaking Zero-Downtime Guarantee for some Sql Server users

This release introduces a database migration that breaks our zero-downtime guarantee for a subset of users matching all the following criteria:

  • using SQL Server
  • the first install of Smile CDR was 2024.08.R01 or later (i.e. 2024.08, 2024.11, or any release in 2025).
  • users who use or wish to use case-sensitive FHIR IDs (client-assigned resource IDs that differ only in case)

The Issue

Previously, when using client-assigned FHIR resource IDs that differ only in case, for example:

PUT /Patient/PatientA PUT /Patient/patientA

would either result in two versions of the same resource, or have the second request would fail. However, by the FHIR spec, this should create 2 distinct resources. This behaviour has now been corrected as part of this HAPI-FHIR issue.

Fixing this requires a database migration that is not compatible with zero-downtime upgrades.

Is your database impacted?

If you meet the criteria above, and want to determine if your database is affected, run the following diagnostic SQL query to check:

SELECT CASE CHARINDEX('_CI_', COLLATION_NAME) WHEN 0 THEN 0 ELSE 1 END  FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = SCHEMA_NAME()
AND TABLE_NAME = 'HFJ_RESOURCE'
AND COLUMN_NAME = 'FHIR_ID'

Users who see:

  • a 1 use case-insensitive collation and are affected
  • a 0 are unaffected

Action required to skip migration and enforce zero-downtime

If the case-sensitive FHIR ID behaviour is not required for your use case, and you wish to preserve zero-downtime upgrades, you may bypass this migration by using the following smileutil command: bin/smileutil migrate-database ...<args>... --skip-versions 8_8_0.20251208.10,8_8_0.20251208.20,8_8_0.20251208.30,8_8_0.20251208.40,8_8_0.20251208.50 See the migrate database docs for more information.

Changes

CDA Exchange+ module now supports exporting History and Physical Notes with LOINC code 34117-2.

Subjective narrative section is now supported on import and export of CDA documents through CDA Exchange+ module.

Objective narrative section is now supported on import and export of CDA documents through CDA Exchange+ module.

When importing a CDA document through CDA Exchange+, depending on the contents of the author header it will either create a PractitionerRole, Practitioner, Device or Organization as the composition's author.

Added two new permissions: FHIR_OP_INITIATE_BULK_DATA_EXPORT_GROUPS_MATCHING and FHIR_OP_INITIATE_BULK_DATA_EXPORT_PATIENTS_MATCHING. These permissions grant users the ability to perform bulk export on Groups or Patients that match a defined FHIR query in the arguments of the respective permission. For example, an argument of ?identifier=foo|bar will allow users to perform bulk export on Groups/Patients that have the identifier foo|bar. See the bulk export documentation or the roles and permissions documentation for more details.

The documentation system now supports YAML Front Matter in markdown files, enabling automatic cross-linking between related pages. Each documentation page can specify its id, title, tags, and related pages in Front Matter metadata. The system automatically generates tag pages and displays related articles in a sidebar, improving documentation navigation and discoverability.

Added support for Oracle Database 23ai. The Oracle JDBC driver has also been upgraded to version 23.6.0.24.10 to support the new database version. The feature also include fixes to prevent the driver from leveraging Oracle 23 newly added support for boolean type which would break schema based initialization and future migrations.

Added remote debugging support to SmileCdrContainer for Testcontainers-based integration tests. The new withDebugEnabled() and withDebugEnabled(boolean) methods allow developers to attach a remote debugger to Smile CDR instances running inside Docker containers. When enabled, the container exposes port 5005 for debugger connections. See the documentation for more details.

Added support for parameterized consent policies in the Consent Module. Parameterized policies allow configuration through URL query parameters (e.g., PolicyName?param=value) and support AND/OR logic for multi-valued parameters. This includes the new RedactFhirPathsWhen built-in policy which can conditionally redact FHIR resource elements based on resource type, FHIRPath expressions, and the user's consent purpose. See the Built-in Policies documentation and Consent Module Overview for details.

The $expunge operation now supports deletion of externalized resource bodies from external object storage. See Expunging Externalized Resources for more information.

A new interceptor has been added to the MDM module that automatically enables MDM expansion for bulk export operations when the user has the FHIR_AUTO_MDM permission and MDM expansion is enabled in storage settings. This allows bulk exports to automatically include linked MDM resources (golden resources and their source records) when appropriate permissions are granted.

A new $sdh.s2s.consent-status operation has been added to the S2S module that can be used to retrieve a list of health plans/payers a member has opted in/out with.

CDA Exchange+ module now supports exporting Progress Notes with LOINC code 11506-3.

a new $sdh.s2s.plans operation has been added to the S2S module that can be used to retrieve a list of health plans from a registered payer.

Integrate the P2P batch job transaction log steps into the new Transaction Log

A new $sdh.pdex.member-provider operation that will return a bundle of Organizations representing a member's attributed healthcare providers.

A new dao_config.allow_database_validation_override configuration option has been added to the FHIR Storage module. When enabled, database-stored terminology resources (CodeSystem, ValueSet, etc.) take precedence over built-in HL7 definitions during validation.

Added connection pool configuration settings for tuning external object storage (AWS S3, Azure Blob Storage, MinIO) performance. See External Object Storage Performance Tuning for more information.

Course of Care narrative section is now supported on import and export of CDA documents through CDA Exchange+ module.

Enabled custom processing for Questionnaire/$questionnaire-package in the Prior Auth PAS module via Camel. This modification allows clients to override and define their own custom processing logic through Camel configuration.

The CDA Exchange+ module now uses the uri http://hl7.org/fhir/sid/us-npi for the National Provider Identifier in Practitioner resources.

Added a system property for the unusual case where tenant IDs were populated before the maximum tenant limit was configured.

PatientMergeProcessor has been added to enable resource $merge FHIR operation for Patient and other resource types in message-driven workflows.

ReplaceReferencesProcessor has been added to enable $replace-references for updating resource references across the database in message-driven workflows.

Add the ability to configure the Prior Auth CRD Module CDS Hooks with a JSON file containing the CDS Hook definitions.

The Bulk Patch and Bulk Patch Rewrite History operations are now partition aware, and can work correctly in a MegaScale environment.

Add the ability to configure the Smile Portal Module's custom applications with a JSON file containing the App definitions.

Add a property to the security session classes to hold 'purpose' and 'actor' for use in the CDR consent infrastructure. See Example: Using Consent Purpose and Actor.

Physical Exam narrative section is now supported on import and export of CDA documents through CDA Exchange+ module.

Interventions narrative section is now supported on import and export of CDA documents through CDA Exchange+ module.

Health Status Evaluations/Outcomes narrative section is now supported on import and export of CDA documents through CDA Exchange+ module.

Two new search normalization modes have been added to Smile CDR repository tokenization. These new modes allow elements of type contactpoint and date to be correctly searched.

Add a $next-question operation to the PAS module to allow dynamic Camel routing for Adaptive Questionnaire Requests. With centralized dynamic routing, the updated QuestionnaireResponse will be returned based on the Questionnaire's canonical url.

Updating logging messages and their corresponding types in CDA Exchange+ module to better reflect errors and warnings.

The FHIR_EXTENDED_OPERATION_ON_ANY_INSTANCE and FHIR_EXTENDED_OPERATION_ON_ANY_INSTANCE_OF_TYPE permissions now support an optional FHIR query filter. This allows the restriction of instance-level operations (e.g., $meta-add) to resources matching a specified filter (i.e. Observation/$meta-add?category=vital-signs).

Three new Camel processors have been added to enable FHIR operations in message-driven workflows: ExpandValueSetProcessor (ValueSet $expand), ValueSetValidateCodeProcessor and CodeSystemValidateCodeProcessor (code validation against ValueSets and CodeSystems).

The enhanced mappings for assignedAuthor that were previously implemented for the header of a CDA document have been extended to the entries in the document as well. Assigned author elements will now be transformed into Practitioner, PractitionerRole, Organization or Device resources, as appropriate, in the context of AllergyIntolerance, Condition, DiagnosticReport, Encounter, Goal and Procedure resources, as well as instances of the Annotation data type. Previously, only the Practitioner resource was supported in these contexts.

For Prior Auth CRD module, the default Camel processors now supports processing of appointment-book hook.

Previously, the member-match services used by bulk member match directly would not return operation outcomes when matches could not be performed successfully. Now, when a member match is not found, multiple matches are found or the member match cannot proceed due to an unsupported consent, an operation outcome is returned with the nature of the failure.

The $bulk-member-match operation now includes a ConsentConstrainedMembers group in the response to separately identify members whose match attempt failed due to unsupported consent policies.

The enhanced mappings for assignedAuthor in the Cda Exchange+ module have been further extended to the MedicationRequest, ServiceRequest and DocumentReference resources. The mappings for the Goal resource have been modified to include PractitionerRole as a valid target resource.

It is now possible to perform a FHIR Bulk Export ($export) when operating in MegaScale mode with Patient ID Partitioning Mode active.

For System to System Data Exchange Module, DocumentReference resources created as part of $invoke-export operation now includes metadata related to the exchange.

The FHIR Storage module Tokenization feature now supports the FHIR PATCH operation.

When importing a CDA document, if an author contains both an assigned person and an assigned authoring device, the authoring device element will be ignored given that it's incorrect CDA format. The author will be mapped as either a practitioner or a practitionerRole.

A custom troubleshooting logger has been added for the System to System Data Exchange module.

Added support for Snowflake as a target database for Real-Time Export (RTE). A new SNOWFLAKE value has been added to the list of allowed settings to support Snowflake's OLTP JDBC driver (net.snowflake.client.jdbc.SnowflakeDriver), enabling RTE to export FHIR data directly to Snowflake databases. This includes support for Snowflake Hybrid Tables which provide transactional ACID guarantees with primary key and foreign key enforcement. Additionally, a new handleCreateBatch() method has been added to IRealtimeExportSvc that processes multiple resource messages in a single transaction using JDBC batch operations. This significantly improves performance when exporting to Snowflake by grouping resources by table for efficient batch inserts, using NamedParameterJdbcTemplate.batchUpdate() for bulk operations, preserving insertion order using LinkedHashMap to satisfy foreign key constraints, and processing parent resources (e.g., Patient) before child resources within the same transaction.

Clicking on section link icons in the documentation now copies the URL to the clipboard and displays a brief 'Link copied!' notification.

Prior Auth Modules (CRD, DTR, PAS) and System to System Data Exchange Module moved from Experimental to Trial.

Enhanced patient linkage in $sdh.s2s.invoke-export operation. The DocumentReference.subject field now references the Patient whose data is being transferred. The Provenance resource adds the patient to the list of targets.

Moving to a new maturity model. Updating doc tags and maturity enums.

The CDA Exchange+ module will only attach a nullFlavor='NI' attribute to a section if it has no structured entries when the specification requires one or more. Previously, this attribute was also used in other scenarios.

The CDA Exchange+ module will now use lenient matching rules on CodeableConcept fields when merging resources, which will reduce the incidence of duplication of semantically equivalent codes.

Previously, for PriorAuth CRD module, the default crdApplyProcessor made the $r5.apply call to local repository. This has now been updated and the call can now be made to remote repository.

Previously, when a Camel Route had an exception in the PAS and CRD modules, only a high level exception message was returned to the client, making it hard to troubleshoot. Now, more details about the underlying cause of the error are returned.

The prior-auth CRD error message for missing patient has been improved. Additionally, the endpoint will no longer return a 404 when an internal resource cannot be found.

The CDA Exchange+ module now supports both the 'entries optional' and 'entries required' variants of the Advance Directives section.

In the CDA model, an Allergy-Intolerance Observation may have multiple <author> elements, but in the FHIR model, the AllergyIntolerance resource only allows one recorder. Previously, the CDA Exchange+ module would resolve this cardinality mismatch by selecting the first author in the CDA entry for inclusion during an import operation. This has been changed to select the author with the most recent timestamp.

The CDA Exchange+ module has been updated to apply the new author filtering rule (previously applied only to AllergyIntolerance resources) to more resource types. The mappings will now select the most recent author by timestamp when parsing Condition, Goal, MedicationRequest or ServiceRequest resources and Annotation datatypes.

For System to System Data Exchange Module, $bulk-member-match-sync operation has now been renamed to $sdh.s2s.bulk-member-match.

In the Prior Auth CRD module, the default crdApplyProcessor Camel processor has been split into two separate processors (crdApplyRequestProcessor and crdApplyResponseProcessor) to allow the PlanDefinition/$r5.apply operation to be called externally via HTTP in Camel routes. See the Prior Auth CRD documentation for migration guidance.

Snowflake database driver support has been isolated to the Real-Time Export (RTE) module. The SNOWFLAKE value has been removed from the global DriverTypeEnum and a new RTEDriverTypeEnum enum has been introduced specifically for RTE target database configuration. This prevents Snowflake from being mistakenly used as a CDR persistence option while maintaining full Snowflake support for RTE export targets.

Section numbers (e.g., '3.0.1', '7.0.2') have been removed from documentation page headings, breadcrumb navigation, and the table of contents for a cleaner presentation.

Previously, subscriptions would not trigger when resources are deleted even when the send-delete extension is enabled. This has been fixed.

The logic to skip property substitution (using ${} syntax) for Camel routes and JavaScript was failing when saving configurations for modules that haven't started since server startup. This has now been fixed.

Previously, chained reference searches by users with FHIR_AUTO_MDM could cause a 500 resource not known error. This fix runs those searches without MDM expansion so they return correct results. If a chained search explicitly includes the :mdm modifier, the request is invalid and the server now returns a 400 Bad Request.

Previously, when writing tests using SmileCdrContainer in cdr-public-test-utils it was not possible to customize logging and the logs would not be visible in the docker container as files. This has been fixed.

Add missing agent.type in provenance record in $invoke-export operation

Previously, when creating Consent and Subscription Matcher modules with subscriptions enabled in the persistence module, consent checking was performed for SearchParameter and Subscription resources for async system processes such as SearchParameter initialization, subscription activation, registration and resource matching. This has been fixed such that we now bypass Consent checking using 'Consent' resources by default for these use-cases.

Previously, modules that threw an Exception during CamelContext validation remained in a STARTED state and would not display any logs until the module was stopped. This has been fixed.

Previously, when sending an HTTP request for an unsupported resource type, the HTTP error response message would always include Patient as a supported resource type, even when Patient was not included in the resource type whitelist. This has now been fixed.

Previously, the CDA Exchange+ module would fail to import a CDA document that contained a Basic Occupation Observation if that observation was missing its <value> element. This has been fixed.

When importing and/or exporting through CDA Exchange+ module, the status value for encounter resources was incorrectly mapped or not mapped at all. This has been fixed by correcting the encounter status source and target mappings.

Previously, restarting a module that has delegated validation to a different one via VALIDATION_SUPPORT could potentially cause errors during validation. This has been fixed

Previously, when the CDA Exchange+ module was generating a document for export, it would throw an exception and abort processing if it encountered a reference that it could not resolve. This has been changed to log a warning message, skip the broken reference, and carry on processing the rest of the document.

Fix for CDA export, encounter type when absent, will now display as code with nullFlavor NI.

A new search parameter normalization mode CODE has been added to the Tokenization rules file. This mode can be used to encode and search for values of type code with a required binding, such as Patient.gender.

Fixed an issue in the FHIR Gateway where duplicate records could appear when paginating through sorted search results. The fix ensures deterministic ordering by resource ID when computing page boundaries.

Changes to the user session would sometimes not propogate through to batch jobs. This could affect consent calculations. This has been corrected.

Fixed the problem where the transaction log broker was throwing an NPE for prior-auth CRD Camel transaction logs when no Camel from endpoint was defined

Previously, the CDA Exchange+ module would not include the Problem Section (entries required) as a mandatory section in a Consultation Note document, but it would include the Procedures Section (entries required) as a mandatory section. This has been fixed.

Previously, the CDA Exchange+ module was using a deprecated LOINC code when generating Care Plan documents. The document definition has been updated to use code 18776-5.

Previously, the $sdh.s2s.consent-status operation would not return all Organizations referenced in the Patient's Consent resources. This has been corrected.

Previously, the 'On this page' table of contents on changelog pages displayed 'undefined' for Upgrade Notes sections. This has been fixed.

A regression was introduced in 2025.11.R01 which caused authentication that used the AWS Security Token Service to fail. This was due to a version update of the aws-advanced-jdbc-wrapper dropping the dependency. This dependency is now included manually in Smile CDR.

Previously, when MDM module was running and tokenization was enabled in persistence, creating a Patient resource that linked to an existing golden resource would fail with error. This has been fixed.

Fixed the Consent Demo tutorial to correctly allow access to Patient resources when the patient compartment is blocked. Previously, blocking access to resources in a patient's compartment would incorrectly also block access to the Patient resource itself.

When using a repository with Tokenization enabled, if a rule is set to QUIESCE status and new data is stored with this rule in place, performing an Update Tokenization job could tokenize previously non-tokenized data. This has been corrected.

Previously, Megascale batch bundle operations that included conditional URLs could abort the entire bundle if one or more entries contained a mismatched conditional URL. This fix ensures that resources are processed on a per-entry basis and only failing entries return appropriate errors.

Previously, the CDA Exchange+ module was rendering an extra <assignedAuthor> element when Composition.author was populated with a PractitionerRole. This has been fixed.

There was a bug in the Authorization Logging that reported DENY messages with (no authorized user) if the session was authenticated using client credentials or other system-to-system authentication. This has been corrected, and the log message will now report the DENY log message with the node_id/module_id/client_id instead.

Previously, the CDA Exchange+ module was not enforcing the US Core 5.0.1 constraint that a PractitionerRole resource must contain at least one telecom or endpoint. This has been fixed.

When using MegaScale in named partition modes, numeric resource IDs were allowed to override the requested named partition name/ID, leading to failures. This has been corrected.

When exporting Allergy Intolerance through CDA Exchange+ module, the effective date will now include the low element with nullFlavor NI for FHIR R4. This will fix the validation errors encountered with allergy concern act.

Fix for import issue using cda-to-fhir SDH operation where a SimpleQuantity type value has a missing leading zero. i.e .5 instead of 0.5.

When exporting an encounter through CDA Exchange+ module, if period is null then the effective date of that encounter will now display as nullFlavor NI.

When exporting medication activity through CDA Exchange+ module, the data type of effective date time will be displayed as TS and if it's an effective period it will be displayed as IVL_TS.

A misconfigured migration caused FHIR Storage modules to fail to start if configured for Database Partition Mode on a non-Postgres database.

Previously, an <author> element within a CDA Allergy Intolerance Observation was only being processed by the CDA Exchange+ module if its timestamp was more recent than any other <author> element previously encountered in the section. This has been fixed so that the timestamp will only be compared to other elements within the same entry.

Fixed FHIR Gateway pagination to no longer return an invalid previous link on the first page of search results when one of the gateway targets has no data in Request Tenant Partition Selection Mode.

Removed mapping of issued field from Observation resource due to it being mapped incorrectly from author time.

Updating ID mapping for author organization to correctly map the ID instead of setting it to null.

Previously, the CDA Exchange+ was failing to create <author> elements in the Results section when the corresponding structure in the FHIR model was a PractitionerRole. This has been fixed.

Previous work in the CDA Exchange+ module to enhance the mapping of <author> elements introduced a regression. <author> elements containing only an id were failing to resolve to a reference to a fully populated element with the same id defined elsewhere in the document. This has been fixed.

When exporting Allergy Intolerance through CDA Exchange+ module, a validation error would trigger on the Allergy Concern Act section with status code completed. This issue has been fixed by populating the missing effectiveDate property with a nullFlavor NI whenever clinical status is inactive.

Previously, when a FHIR Storage module was configured to use validation support from a parent module, the $validate operation would fail with an error. This has been fixed.

Fixed the generate-rte-schema CLI command to support SNOWFLAKE and SNOWFLAKE_HYBRID SQL engine types. Previously, using -s SNOWFLAKE or -s SNOWFLAKE_HYBRID would fail with an IllegalArgumentException.

Previously, when Megascale was enabled, POST bundle requests threw a NullPointerException if a resource reference did not include a Partition ID. This has been fixed.

Previously, PriorAuth CRD module would fail to start when CDA Exchange+ module was also configured. This behaviour has been fixed.

Previously, the CDA Exchange+ module would throw an exception while attempting to export an Encounter resource if Encounter.participant.individual contained a reference to any resource other than Practitioner. This has been fixed.

Smile CDR 2025.11.R08 (Euphoria)

 

Release Information

Released 2026-03-27
Codename Euphoria
HAPI FHIR Smile CDR 2025.11.R08 is based on HAPI FHIR 8.6.8, and includes all changes and fixes included in this version. Please see the HAPI FHIR ChangeLog for details about what has changed.

Upgrade Instructions

Changes

Backported from: 2026.05.R01

Previously, the Subscription Submitter was ignoring the scheduled_tasks.async_persisted_resource_processing.processing_interval property, potentially causing Subscription latency by using a hardcoded default interval (5000ms) instead of the user-defined configuration value. This has been fixed.

Smile CDR 2025.11.R07 (Euphoria)

 

Release Information

Released 2026-03-19
Codename Euphoria
HAPI FHIR Smile CDR 2025.11.R07 is based on HAPI FHIR 8.6.7, and includes all changes and fixes included in this version. Please see the HAPI FHIR ChangeLog for details about what has changed.

Upgrade Instructions

Changes

Smile CDR 2025.11.R06 (Euphoria)

 

Release Information

Released 2026-03-05
Codename Euphoria
HAPI FHIR Smile CDR 2025.11.R06 is based on HAPI FHIR 8.6.6, and includes all changes and fixes included in this version. Please see the HAPI FHIR ChangeLog for details about what has changed.

Upgrade Instructions

Changes

Backported from: 2026.02.R01

It is now possible to perform a FHIR Bulk Export ($export) when operating in MegaScale mode with Patient ID Partitioning Mode active.

Backported from: 2026.02.R01

Fixed an issue in the FHIR Gateway where duplicate records could appear when paginating through sorted search results. The fix ensures deterministic ordering by resource ID when computing page boundaries.

Backported from: 2026.02.R01

Fixed FHIR Gateway pagination to no longer return an invalid previous link on the first page of search results when one of the gateway targets has no data in Request Tenant Partition Selection Mode.

Backported from: 2026.02.R01

Previously, when Megascale was enabled, POST bundle requests threw a NullPointerException if a resource reference did not include a Partition ID. This has been fixed.

Backported from: 2026.05.R01

Previously, searching for a Patient by identifier in MegaScale PATIENT_ID or BUCKETED_PATIENT_ID partition mode would return a 400 error when the identifier system matched a pre-resolvable patient identifier system, but no Patient existed with that identifier system. This has been fixed so that the search now correctly returns an empty Bundle.

Backported from: 2026.05.R01

Previously, HL7v2 inbound message processing could fail with a HAPI-2223: Partition IDs have not been set error in MegaScale PATIENT_ID mode when the storage_tenant_name property was left blank. This issue has been fixed.

Smile CDR 2025.11.R05 (Euphoria)

 

Release Information

Released 2026-02-25
Codename Euphoria
HAPI FHIR Smile CDR 2025.11.R05 is based on HAPI FHIR 8.6.5, and includes all changes and fixes included in this version. Please see the HAPI FHIR ChangeLog for details about what has changed.

Upgrade Instructions

This release fixes a regression from 2025.11.R03 in which the DQM module would fail to boot if configured.

Changes

Backported from: 2026.02.R01

Integrate the P2P batch job transaction log steps into the new Transaction Log

Backported from: 2026.02.R01

A misconfigured migration caused FHIR Storage modules to fail to start if configured for Database Partition Mode on a non-Postgres database.

Backported from: 2026.02.R01

Previously, when a FHIR Storage module was configured to use validation support from a parent module, the $validate operation would fail with an error. This has been fixed.

Smile CDR 2025.11.R04 (Euphoria)

 

Release Information

Released 2026-02-02
Codename Euphoria
HAPI FHIR Smile CDR 2025.11.R04 is based on HAPI FHIR 8.6.3, and includes all changes and fixes included in this version. Please see the HAPI FHIR ChangeLog for details about what has changed.

Upgrade Instructions

This release fixes a regression from 2025.11.R03 in which the DQM module would fail to boot if configured.

Changes

Smile CDR 2025.08.R04 (Amplification)

 

Release Information

Released 2026-03-20
Codename Amplification
HAPI FHIR Smile CDR 2025.08.R04 is based on HAPI FHIR 8.4.3, and includes all changes and fixes included in this version. Please see the HAPI FHIR ChangeLog for details about what has changed.

Upgrade Instructions

Changes