Why upgrading an old Apache Fineract 1.x release is a multi-step project
An unpatched Fineract or Mifos X backend that must reach the current 1.x release is a staged migration, not a single version bump. The project creates official releases quarterly, at the end of each quarter, under the ASF release policy, and archives end-of-life releases. Your installed version may therefore be several quarters behind, and the 1.15.0 line that the project lists as current stable is where you need to land. Confirm the exact intermediate stops against the release notes and migration documentation for your source version, because the schema and configuration changes between releases do not form one path that every old deployment can take at once.
The 1.x line is the platform to target because Fineract CN, the microservices rewrite, was deprecated in May 2023 and archived in late 2023 without an official release. Any plan that treats the old backend as a stable base to patch in place should be checked against that fact first. Before you schedule any stop, inventory the database platform, the tenant configuration, the Mifos X web app version and any custom code that edits core sources, since each of these will decide whether a step is a simple rollout or a rebuild. Ask your team or your partner to produce that inventory in writing, then map it to the stops listed in the Fineract platform documentation.
What changes between old 1.x releases and the current release
This table compares the changes that most often break an old Fineract or Mifos X backend when it moves to the current 1.15.0 release. Read each row as a checkpoint: confirm the impact on your data and configuration, then assign the action before any upgrade work starts. The main takeaway is that date storage, migration execution and database choice need decisions first, because they are hard to reverse later.
| Change | Impact | Action needed |
|---|---|---|
| UTC date time storage (introduced in 1.8.0) | Instances that did not run in UTC may have written dates that MySQL reads incorrectly, and migration scripts can then misbehave. | Confirm the time zone of every past instance, check stored dates against source records, and test migration scripts on a copy first. |
| Liquibase migrations on write instances | Schema changes run only on write instances, so a scaled deployment without a write instance will not reach the new schema. | Identify the write instance, or run migrations through a separate liquibase-only instance before the application rollout. |
| Liquibase-only Spring profile on Kubernetes | Migrations can run as a separate step, which keeps application pods from racing to change the schema. | Plan a migration job that completes before new application pods start, and define how it is rolled back. |
| Deprecated fineract_tenants_* variables | The older variables still work for backward compatibility but are no longer the recommended configuration. | Inventory every fineract_tenants_* setting and move it to the FINERACT_HIKARI_* equivalents, then retest tenant connections. |
| MariaDB and MySQL deprecation under FSIP-9 | The project recommends PostgreSQL and lists MariaDB and MySQL as deprecated, and the official Docker image ships only the PostgreSQL JDBC driver. | Confirm the current database platform, record the support position, and decide whether a database move belongs in the same project. |
| PostgreSQL as recommended database | The official image and recommended configuration assume PostgreSQL, so older MySQL-based stacks need extra build or configuration work. | Ask your team to confirm the target database and its version before estimating the upgrade scope. |
| Current stable release 1.15.0 | Fineract documentation for 1.15.0 was built on July 10, 2026, and the project publishes quarterly releases with end-of-life archiving. | Target the current stable release, check its release notes, and confirm the matching Mifos X web app version. |
How the 1.8.0 UTC change can distort historical dates
Release 1.8.0 changed how Fineract stores date and time values, moving to UTC date time storage. The project's README warns that if a previous instance did not run in UTC, prior dates can be read wrongly by MySQL and cause issues when running database migration scripts. For a long-unpatched backend, this means the risk is not only in the new code. Historical loan disbursements, repayment schedules, transaction dates and business dates written under an older server time zone may be interpreted with an offset when the upgrade path reads them, and a migration script that compares or transforms those values can then silently move records to a different day. Treat date integrity as a pre-upgrade gate, not a post-upgrade bug report.
Before running any Liquibase migration, confirm the time zone the database server and the Fineract application servers used when the data was written, and compare it with the zone the instance runs in today. Check the database session and server time zone settings for your platform, and check the JVM time zone on the application hosts. Then sample stored date and timestamp values for known transactions, such as a disbursement you can verify against a source document, and compare what the database returns with what the Fineract API shows for the same record. Run these checks against a restored copy of production, not the live database. The exact commands, column types and settings differ between MySQL, MariaDB and PostgreSQL, so confirm them against the Fineract README and the documentation for your target database platform before you rely on them.
Record the results as part of the upgrade plan. If the samples show a consistent offset, decide with your finance and operations owners whether the data needs correction before or after migration, and who signs off on that decision. If the samples are clean, keep them as evidence for the regression tests. Also confirm which fineract_tenants_* or FINERACT_HIKARI_* settings the target release reads, since the README says the older variables still work for backward compatibility while it strongly encourages the newer ones, and make sure the time zone you verified matches the one the new instances will use.
What to prepare before the first upgrade step
Six preparation items sit between the current Fineract or Mifos X backend and the first Liquibase run. Each produces an artifact you can check, and together they decide whether a failed upgrade is a rollback or a recovery project.
Verified full database backup
Take a full backup of every tenant database, then restore it into a scratch server and confirm the restored copy starts and answers API calls. A backup that has never been restored is an assumption, not a recovery point. Record the exact Fineract version and schema state at the time of the backup, and confirm that the tenants database is included in the set.
Inventory of custom code and variables
List every custom change that edits core Fineract sources, every custom module, and every deployment setting that still uses the older fineract_tenants_* variables. Each item needs an owner and a decision: port, replace, or retire. Core source edits are the change most likely to conflict with a new release, so they need the earliest review.
Copy of environment and tenant configuration
Export the current environment variables, container or Kubernetes manifests, and the tenant entries from the tenants database. Store them in version control with the secrets removed and kept in your secret store. Note the instance type of each process (read, write or batch), because the upgrade steps depend on which instance runs Liquibase.
Production-like test environment with restored data
Build a test environment with the same Fineract release, database platform, and instance layout as production, loaded with the restored copy. Run the upgrade there first and time it. Confirm the database platform is PostgreSQL, since the project recommends it and MariaDB and MySQL are deprecated under FSIP-9. Check the date values in the restored data against the UTC behavior introduced in 1.8.0 before you start.
Matching web app and integration inventory
List the Mifos X web app version, every system that calls the Fineract REST API, and every event or webhook consumer. Identify which web app release matches the target Fineract version and which integrations use the Fineract-Platform-TenantId header. Each consumer needs a named contact who can run regression tests on their side during the upgrade window.
Agreed rollback criteria
Write down, before the window opens, the conditions that trigger a rollback, who can make that call, and how long the team waits before deciding. Cover failed Liquibase changesets, failed reconciliation of accounting or loan balances, and failed Close of Business Day runs. Rollback is only safe while the restored backup is still the source of truth, so define the point after which writes resume on the new release.
The upgrade sequence from an old 1.x release to the current release
The sequence moves a long-unpatched Fineract or Mifos X backend forward one supported stop at a time, so each schema change, configuration change and behavior change is verified before the next one starts. It ends with the backend, app instances and the Mifos web app on matching current versions and a documented rollback point.
Freeze changes and take verified backups
The client's operations owner freezes configuration, product and data changes, and the upgrade team takes a full PostgreSQL or MySQL backup of every tenant database, including the tenants database, along with copies of the environment variables, custom code and the Mifos web app build. The step is done when a restore of the backup has been tested on a separate database server and the restored schema matches the source. Ask the vendor or your DBA to confirm the exact dump tooling for your database engine before you begin.
Confirm the source version and its upgrade path
Identify the exact Fineract or Mifos X release currently running, including any patches, by checking the deployed image tag, the build metadata and the Liquibase changelog state in each tenant database. Read the release notes for that source release and the releases between it and the current 1.15.0 stable release to list every required intermediate stop. The step is done when the team has a written, ordered list of stops and each stop is tied to a release note entry, and the list has been reviewed by the application owner.
Verify UTC date state before any migration
Check whether the old instance ran in UTC, since release 1.8.0 introduced UTC date time storage and the project warns that earlier data written outside UTC can be read incorrectly by MySQL and can cause problems when migration scripts run. Compare stored timestamps for known transactions against the expected local and UTC values in a test restore. The step is done when the team has either confirmed the date state is consistent or agreed a correction plan with the business owners, and the result is recorded in the upgrade log.
Move tenant configuration to FINERACT_HIKARI_* variables
Replace the older fineract_tenants_* environment variables with their FINERACT_HIKARI_* equivalents in every app, batch and write deployment. The older names still work for backward compatibility, but the project strongly encourages the newer ones, so the change removes an upgrade dependency. Confirm each value against the previous configuration, including pool sizes and connection timeouts. The step is done when a diff of old and new environment settings has been reviewed and a test instance starts and connects to every tenant database.
Run Liquibase on one instance per intermediate stop
At each stop, run the Liquibase migrations on a single write instance, or on a liquibase-only instance on Kubernetes, while no other instance is serving traffic. Liquibase migrations run only on write instances, so the team should not let several app instances race on the schema. Record the changesets applied and the database version after the run. The step is done when the changelog shows every expected changeset as applied and the application starts cleanly against the migrated schema. Keep the database backup from step one as the rollback point for this stop, and take a fresh backup before each later stop.
Run regression checks at each stop
Before moving to the next stop, test the business paths that the upgrade is most likely to affect: loan and savings product definitions, accounting mappings and journal postings, and a Close of Business Day run on a copy of production data. Compare results with outputs captured on the source version, including balances, schedules and posted entries. Where custom code touches core behavior, rerun those tests too. The step is done when the differences are either zero or explained and signed off by finance and operations, and the team records the rollback point for that stop.
Move app instances to the current backend version
After the final stop, roll out the current Fineract image to read and batch instances, keeping write and liquibase-only roles as configured for the environment. Confirm that custom code has been rebuilt against the new sources and that it does not edit core files in ways the new release overrides. Check that the batch job and read instances connect to the migrated database and that health endpoints report ready. The step is done when all instances report the current version and smoke tests pass against each tenant.
Align the Mifos web app and close the upgrade
Upgrade the Mifos web application to the release tagged to the same Fineract version, check its environment variables against the current documentation, and run staff workflow tests for client onboarding, loan disbursement and savings transactions. Confirm TLS settings and the changed default credentials are in place. The step is done when the front end and backend versions are recorded together, the workflow test results are signed off, and the team has written down the rollback procedure for the release window.
Why custom edits to core sources make the upgrade harder
Custom edits to Fineract core sources must be rebased or re-applied on every target release, and that work repeats for each step of the upgrade path. A patch that changed a service class, a repository query or a REST resource in 1.x does not carry forward automatically when the upstream files have moved. Each target release needs a fresh merge, a compile, and a review of whether the edit still does what the business needs. The longer the instance has been unpatched and the more edits it carries, the more of these merges the team inherits at once.
Core edits also collide with two things that change between releases: Liquibase changesets and the API contract. If a customization added columns, tables or indexes by hand, or changed an existing changeset, the Liquibase history on the target database may no longer match the code, and the migration can fail or silently diverge between environments. If a customization altered a request or response shape, any generated client, batch request or downstream integration built on that shape must be checked as well. Confirm, for each target release, which schema changes and API changes the project documents, and compare them against your own edits before you run any migration on a copy of production.
Classify every customization before the first rebase. Mark each one as removable (the business need is gone or the platform now provides the feature), re-implementable (the need remains and a documented extension point such as a custom job, business step, processor or event listener can deliver it without editing core), or still needed (no supported mechanism covers it, so the edit must be carried and tested on every release). Only the last category should keep growing the patch set. Whether a given extension mechanism is available and stable in each target release is something to confirm in the release documentation and the source for that tag, not to assume from the 1.x line as a whole.
What makes an old Fineract upgrade longer or costlier
This table lists the factors that most often stretch an upgrade from an older 1.x release or Mifos X backend to the current release, and what each one does to effort. Use it to size the work before asking for a quote, and to decide which facts to gather from your own environment first. The main takeaway is that release distance, data volume and the absence of a realistic test environment usually matter more than the upgrade steps themselves.
| Driver | Effect on effort | What to check |
|---|---|---|
| Number of intermediate releases | Each release between your source and target can add a Liquibase step, a regression cycle and a set of configuration changes to review. | List every release tag between your current version and the target, and confirm the upgrade path in the project's release notes. |
| Data volume and tenant count | Larger schemas and more tenants lengthen migration runs, backup and restore windows, and per-tenant verification. | Record row counts for the largest tables and the number of active tenants, and time a restore of a production copy. |
| Close of Business Day runtime | On deployments with millions of accounts, a single COB run can take several hours, so test cycles and cutover windows grow. | Measure COB duration on a production-sized copy, including any remote partitioning setup, before fixing the cutover plan. |
| Custom code that edits core sources | Patches to core Fineract classes must be re-applied, rebased and retested on every release, which often costs more than the platform upgrade itself. | Diff your build against the upstream tag, and classify each change as extension, configuration or core edit. |
| Integrations and event consumers | Each API client, reporting feed, webhook or event consumer needs contract checks and regression tests, and some may need changes for new behavior. | Inventory every system that calls the API or consumes business events, and identify owners who can test against a staging copy. |
| MySQL or MariaDB in use | A database move to PostgreSQL may be needed alongside the version change, adding schema transfer, data reconciliation and separate cutover planning. | Confirm the database engine and version in use, and review the project's standardization guidance (FSIP-9) before choosing a sequence. |
| UTC date history | Instances that did not store dates in UTC before the 1.8.0 change need date checks on historical records and migration scripts. | Check server and database time zone settings from the period before the upgrade, and sample historical transaction dates. |
| Test environment with real data | Without a production-like copy, defects surface in production, and reconciliation and sign-off take longer. | Confirm that a refreshed, anonymized copy of production data, with matching configuration and integrations, is available for repeated test runs. |
Questions teams ask before upgrading an old Fineract release
What drives the cost and effort of upgrading an old Fineract release?
The main drivers are how far the source version sits behind the current release, how much custom code edits core Fineract sources, and how much data and how many integrations must be checked afterward. A deployment on a 1.x release that has not been patched for a long time usually needs more upgrade steps, more schema changes to review and more regression testing than a recent one. Custom code that was copied into a forked tree adds merge and retest work, because each core change must be re-examined against the new sources. Costs split into the partner's fixed-scope work, your team's time for testing and approvals, and infrastructure for staging environments. Ask any quote to list the source version, the target version, the number of environments, and which custom modules and integrations are in scope.
How long does a Fineract upgrade from an old 1.x release take?
No single duration can be given until the source version and data size are known, because both change the number of migration steps and the volume of data that must be validated. The Fineract README notes that the Close of Business Day job can run for several hours on deployments with millions of accounts, so a large tenant needs longer rehearsal runs. Timing also depends on how many tenants exist, whether custom code needs rework, and how long your staff take to sign off on products, accounting and end-of-day results. Ask for a timeline that lists each upgrade step and the rehearsal runs separately, and check the release notes and documentation for the version-specific changes that affect the plan.
What does the upgrade need from our own team?
Your team needs to provide a staging copy of production data, access to the current database and application configuration, and named people who can confirm product, accounting and close-of-business behavior after each step. Someone must own the decision to proceed, the rollback criteria and the change window. Your integration owners must confirm which API consumers, batch jobs and event subscribers depend on the current behavior. Your security team should review the credentials and TLS settings that change with the new configuration. Agree these responsibilities in writing before work starts so that testing does not stall while people are waiting for access or sign-off.
Can an in-house team upgrade an old Fineract release on its own?
An in-house team can do it if it has experience with PostgreSQL administration, Liquibase, Java application operations and Fineract's configuration model, and if it can dedicate time to staging tests. The Fineract README states that a production deployment can be complex, costly and time-consuming and that the project does not provide a comprehensive production deployment guide. Teams that lack that background, or that carry a lot of custom code, often bring in a partner for planning and rehearsal and keep the cutover in-house. Decide on this split by listing the skills you have, the custom changes you carry and the time you can commit before the cutover date.
Can we skip intermediate releases and upgrade in one jump?
Whether a jump is possible depends on the database migration path between your source version and the target, so confirm it against the release notes and the project documentation before you commit to a plan. Schema changes are applied in order through Liquibase, and a release may depend on the state left by the one before it. Skipping steps therefore raises the risk that a migration fails in an unexpected place. A safer plan rehearses each required step in staging on a copy of production data and records the result of each one. Ask for the exact list of intermediate versions your plan uses and the reason each one is needed.
What happens if a migration step fails during the upgrade?
A failed step should stop the upgrade and trigger the rollback plan agreed before the change window. Because Liquibase records applied changes, a partially applied step can leave the schema in a state that needs manual review, so the plan must include a restore from a verified backup taken immediately before the step. Rehearsals in staging reveal most failure modes in advance, including data that does not fit a new constraint. Record the error, the step and the data involved, then decide whether to fix forward or restore. Ask any partner to describe its rollback criteria, backup verification and who makes the go or no-go call at each step.
Does the Mifos web app have to be upgraded at the same time?
The Mifos web app is a separate front end, and Fineract is headless, so the backend can be upgraded first only if the existing front end still works with the new REST API. The Fineract README points to the Mifos X web application as the front end used in its Kubernetes example, which means the two should be planned together. Check the version pairing and any environment variables the web app requires, then test staff workflows such as client onboarding, loan disbursement and end-of-day runs. Custom front-end changes need the same regression testing. Confirm the pairing in the web app documentation before you set the cutover order.
Do custom changes to Fineract core sources block the upgrade?
Custom changes to core sources do not block an upgrade, but they usually make it slower and riskier because each edit must be reapplied to the new release and tested again. Changes made inside a fork require a merge, and conflicts appear wherever the new release touched the same classes or migrations. The safer approach is to move custom logic into extensions that do not edit core files, then remove the core edits during the upgrade. Start by inventorying every change against the upstream source, including any database objects created outside Liquibase. That inventory is usually the largest single driver of effort in a legacy upgrade.
How DeployOpen scopes and delivers a Fineract upgrade
DeployOpen plans, implements, tests, documents and supports self-hosted open-source platforms inside your own infrastructure, including upgrades of older Fineract and Mifos X backends. Each legacy upgrade starts with a written scope that records the source release, database, custom code and integrations before any change is made to a running system.
How we scope
- Record the current Fineract or Mifos X version, database platform and tenant configuration before estimating work.
- Inventory custom code that edits core sources, and list which of it must be rebuilt against the target release.
- Agree in writing which upgrade steps, environments, test cases and handover items are in the fixed scope.
How we build
- Plan the release path step by step through Liquibase changes, rather than jumping directly to the current release.
- Check UTC date handling against the instance's historical time zone, especially where MySQL held earlier data.
- Move deprecated tenant connection variables to the FINERACT_HIKARI_* settings and verify each tenant after the change.
How we hand over
- Deliver a runbook covering the upgrade sequence, rollback points, configuration changes and post-upgrade checks.
- Document every rebuilt custom component, its build inputs and its tests so your team can maintain it.
- Walk your operations and development staff through the environment, then confirm the handover checklist in writing.
How we support
- Offer ongoing support, upgrades and continuous testing as a retainer after the fixed-scope work completes.
- Track each new quarterly Fineract release so your next upgrade starts from a current, tested baseline.
- Confirm with your team the support hours, escalation contacts and maintenance windows before the engagement closes.

