Fire Arrow Server 2.6.0
Fire Arrow Server 2.6.0 has been released.
- (breaking) Azure Queue subscription messages omit the resource body unless
fire-arrow.subscription.azure-queue.include-full-resourceistrue - (breaking) Developer tools in the administration UI require the
developer-toolsrole, or administrator access - (feature) Administration navigation is grouped into Clinical, Operations, and Dev Tools, and the UI ships in a light theme
- (feature) Patient list columns, search, and sort can be set with
fire-arrow.ui.patient-list - (feature) The patient chart adds a Medications tab and optional tabs from
fire-arrow.ui.patient-chart - (feature) Practitioner records open on a detail page
- (bugfix) An Azure Queue message over the size limit is delivered without the resource body
- (bugfix) The clinical data tab loads observations again
- (bugfix) Cluster sessions can use a passwordless database login, and a failed peer check no longer floods the log
- (maintenance) Jackson databind and administration UI security updates
Azure Queue Messages Omit the Resource Body
Azure Queue subscription delivery can embed the changed FHIR resource in each message. That copy is convenient for a consumer that does not call the FHIR API, and it is also how a large resource runs into the queue's size limit.
Starting with 2.6.0, fire-arrow.subscription.azure-queue.include-full-resource defaults to false. Each message still carries resourceType, resourceId, resourceVersionId, and eventType, plus the subscription identifiers. payload and payloadContentType are omitted. Read resourceId and fetch the current resource through the FHIR API, where the caller's authorization applies.
The Azure container image sets include-full-resource to true in its bundled configuration, so that image keeps embedding the resource. A deployment that uses the default server configuration and does not set the property switches to messages without payload.
Breaking Change
Set fire-arrow.subscription.azure-queue.include-full-resource to true (FIRE_ARROW_SUBSCRIPTION_AZURE_QUEUE_INCLUDE_FULL_RESOURCE=true) before upgrading when a consumer reads payload. The Azure image already sets this. Other deployments that omit the property must set it themselves to keep the embedded resource.
REST hook and WebSocket subscriptions are unchanged. Queue delivery stays off unless fire-arrow.subscription.azure-queue.enabled is true.
Developer Tools Require a Role
The administration UI used to show the resource browser, Capability Statement, query consoles, API documentation, encoding options, and server history to every signed-in user. Server Config was already limited to administrators.
Starting with 2.6.0, those pages require the developer-tools UI feature. Assign Developer Tools under Dashboard Access when editing a PractitionerRole. An administrator (a token with the configured admin scope) still sees them without that feature. When authentication is disabled, the UI still grants every feature, including developer tools.
The same gate covers:
| Page | Who can open it |
|---|---|
| Resource browser, Capability Statement, GraphQL, CQL, HFQL, API documentation, Credentials, server history, encoding options | developer-tools, or an administrator |
| Server Config | An administrator (the admin scope already implies developer-tools) |
| Bundle uploader | bundle-uploader, or an administrator |
Show Credentials is no longer in the header. Open Credentials under Dev Tools. GraphQL, CQL, HFQL, and API documentation moved from the header into that same group.
Breaking Change
After upgrading, assign developer-tools to every non-administrator who still needs those pages. Until you do, those users see the clinical and operations tools their other roles allow, and a direct link to a developer page is refused. Administrators and deployments with authentication disabled see no change. Server Config remains an administrator page.
Administration Navigation and Theme
The administration UI is regrouped:
| Group | What it contains |
|---|---|
| Clinical | Patients |
| Operations | Plan definitions, care plans, questionnaires, practitioners, devices, related persons, organizations, roles |
| Dev Tools | The developer pages in the table above |
Home sits above those groups. A signed-in user who is not an administrator and who can see only one group gets that group's links as a flat list, without a section heading and without Home. Administrators, and anyone who can see more than one group, keep the grouped menu.
The UI ships in a light theme. A choice saved in the browser, or the operating system's dark preference when nothing is saved, still applies. The header theme toggle is unchanged.
Configurable Patient List
The patient list on the administration UI is a table driven by configuration. With fire-arrow.ui.patient-list omitted or empty, the list shows name, birth date, gender, email, and phone; searches by name; and sorts by name, birth date, or last updated. There is no banner about using the built-in list. An invalid document shows the validation errors and falls back to that same built-in list.
A non-empty document replaces the built-in list as a whole. Columns are built-in ids (name, birthDate, gender, email, phone, lastUpdated) or a custom column with a FHIRPath path and a locale map for the label (default is required). retrieve: Patient:organization is sent as _include. retrieve: Condition:patient is sent as _revinclude. retrieveWhere further limits included resources. A custom column without retrieve may set sortParam to a Patient search parameter. Search and sort stay in the page address (q, sort, sortDir), and opening a patient keeps them so Back returns to the same list. The count is Bundle.total.
fire-arrow:
ui:
patient-list:
columns:
- id: name
weight: 2
- id: birthDate
- id: gender
- id: email
- id: phone
sortFields:
- id: name
- id: birthDate
search:
kind: fields
fhirParams:
- name
- identifier
filters: []
The previous list searched by name, identifier, and date of birth, and it had a create control. To search by identifier or birth date, set search.fhirParams on a complete patient-list document that also lists the columns and sort fields. A document that omits columns is invalid: the UI shows the errors and keeps the built-in list. This list has no create control. Create a Patient with the FHIR API, or from the resource browser when you have developer tools. Practitioner, device, and related-person lists are unchanged.
Patient Chart and Medications
Opening a patient from that list opens a chart. The built-in tabs are Details, Medications, and Clinical data, in that order. ?id=<patientId>&mode=timeline still opens Clinical data.
Details is the demographics form. A user with patient-manager can edit; patient-viewer is read-only. The chart offers one-time token generation when Patient/$generate-one-time-token is enabled. Durable token generation is no longer on this page. It remains on the resource browser and on Patient/{id}/$generate-durable-token.
Medications lists active MedicationRequest resources for the patient. A user with patient-manager searches the medication catalog, sets dose, unit, interval, start date, times, and an optional duration, and saves one active MedicationRequest per schedule. A scheduled dose requires at least one time. An as-needed dose does not. Remove asks for confirmation and deletes that request. A user with patient-viewer sees the list only. An active request this form cannot represent is still listed. A manager can remove it. Edit is not offered for that request.
Optional tabs append after the built-in ones when fire-arrow.ui.patient-chart is set. Each tab is a set of sections. The supported element is latest-value: the newest matching resource for the open patient, narrowed by an optional system|code token. Do not reuse the built-in ids details, medications, or clinical-data. The server rejects details and clinical-data.
fire-arrow:
ui:
patient-chart:
tabs:
- id: observations
title:
default: Observations
icon: activity
sections:
- title:
default: Heart rate
element:
type: latest-value
resourceType: Observation
code: http://loinc.org|8867-4
valueField: valueQuantity
When fire-arrow.ui.patient-chart is omitted or tabs is empty, only the three built-in tabs appear. An invalid document returns validation errors and no extra tabs.
Practitioner Detail Page
Opening a practitioner from the administration list opens a detail page for that record: name and contact details, edit for a user with practitioner-manager, and one-time token generation when Practitioner/$generate-one-time-token is enabled. Read-only users with practitioner-viewer see the profile without edit. Durable token generation is no longer on this page. It remains on the resource browser and on Practitioner/{id}/$generate-durable-token.
Device and related-person records still use the previous list and side panel, including durable token generation there.
Bug Fixes
Oversized queue messages were dead-lettered
Azure Storage Queue accepts a message of up to 64 KiB. A resource with contained content — a CarePlan produced by PlanDefinition/$apply is a typical case — can exceed that. Delivery is supposed to send the message again without the resource body.
That retry never ran when the queue's "message too large" response arrived wrapped inside another error. The server treated it as a temporary failure and sent the same oversized body again until the notification was abandoned.
Starting with 2.6.0, a too-large response sends the notification without payload, with the same notificationId as the attempt that carried the body. Fetch the resource with resourceId. This applies when include-full-resource is true, including the Azure image. A consumer that requires payload must accept that a resource over 64 KiB arrives without one.
Clinical data tab failed to load
Clinical data searches were sent to a doubled FHIR path (/fhir/fhir/...). The server rejected them as an unknown resource type, and the tab showed a load failure. Timestamps written as yyyy-MM-dd HH:mm:ss also failed to parse, so a summary or graph that depended on them stayed empty.
Starting with 2.6.0, those searches use a single FHIR base path, and that timestamp form parses. The tab loads the patient's observations.
Passwordless databases left the cluster degraded
Cluster coordination opens its own database sessions, separate from the connection pool. A passwordless login configured only on the pool — for example Azure managed identity — did not apply to those sessions. The startup check failed with a missing-password error. With fire-arrow.cluster.enabled left at auto, the instance logged an error and ran on its own, which does not coordinate with other replicas. The peer check then logged a warning on every heartbeat.
Set the same authentication plugin on fire-arrow.cluster.connection-properties so those sessions can log in. The startup check can then pass and cluster mode can start. See the Cluster runbook for the rest of a multi-instance deployment.
fire-arrow:
cluster:
connection-properties:
"[authenticationPluginClassName]": com.azure.identity.extensions.jdbc.postgresql.AzurePostgresqlAuthenticationPlugin
If a session still cannot be opened, the instance logs one error and does not keep checking peers. Other degraded failures still check. The warning is logged at most once per fire-arrow.cluster.degraded-warn-interval (default 1 hour). Every failure increments fire_arrow_degraded_peer_check_failures. Deployments that already pass the startup check are unchanged.
Dependency Upgrades
2.6.0 updates Jackson databind to 2.22.3 on the server runtime, addressing CVE-2026-91776 and CVE-2026-91777. Both are denial-of-service issues in deserialization: an unbounded cache of unknown type ids when polymorphic fallback is enabled, and quadratic work completing identity references in reverse order.
The administration UI updates Next.js to 16.3.8, addressing CVE-2026-94483, CVE-2026-94484, CVE-2026-94485, CVE-2026-94543, CVE-2026-94544, GHSA-vcvr-r3jv-pc5j (remote code execution in next/og when attacker-controlled values are rendered into an image), and GHSA-h694-7cp9-m8p3 (a cache leak across root parameter values). CVE-2026-94486 applies to the Next.js development server only. The FHIR API is unaffected by the Next.js advisories.