Why the Apache NiFi 2 Java 21 requirement sets the upgrade order
If your team runs NiFi 1.x and must move to NiFi 2, Java 21 is the first gate, and it sets the order of everything that follows. NiFi 2 requires Java 21 as its minimum runtime, so the JDK on every host or container image has to be verified and updated before any flow is touched. The NiFi project has also stopped maintaining the 1.x line: according to the NiFi downloads page, NiFi 1.28 is the last minor release of version 1 and 1.28.1 reached end of support on December 8, 2024. The project explains that 1.x cannot be patched further because it depends on Jetty 9.4, Spring Framework 5.3 and AngularJS 1.8, and those components cannot be upgraded within that line. Staying on 1.x is therefore a security and supportability decision, not a neutral one.
The NiFi migration guidance sets the path. You must first upgrade to NiFi 1.27.0 before moving to 2.0.0, and the flow configuration file changes from flow.xml.gz to flow.json.gz as part of that path. Treat the Java 21 change as part of the same sequence, not as a separate host task. Confirm that your 1.27.0 staging environment runs cleanly on the JDK you plan to use with 2.x, because a flow that only works after the move to 2.0.0 is harder to roll back. Plan the rehearsal against the current NiFi 2 release line, which the downloads page lists as 2.12.0, and confirm the exact upgrade steps for your starting version in the NiFi migration guidance before scheduling any change window.
What changes in NiFi 2 for Java 21 and the host
This table lists the NiFi 2 changes that affect the host, JVM and startup scripts, with the impact of each and the action your team needs to take. Read each row against your current 1.x deployment, and treat the Python row as relevant only if your flows use the optional Python processors. The main takeaway is that the Java 21 runtime change reaches every node, image and build agent, not just the NiFi application.
| Change | Impact | Action needed |
|---|---|---|
| Java 21 minimum runtime | NiFi 2 requires Java 21 on every node. Older JDKs on hosts, container base images or build agents will not run it. | Confirm the Java 21 JDK on every node, image and build agent, and rebuild custom NARs against it. |
| java.net.preferIPv4Stack no longer set by default | The default bootstrap configuration no longer forces IPv4. Hostname resolution and IPv6 behavior may change on dual-stack hosts. | Test name resolution on each host, and set the property in bootstrap configuration if your network needs IPv4 only. |
| Windows scripts replaced by nifi.cmd | Separate scripts such as run-nifi.bat are replaced by nifi.cmd with sub-commands. Service wrappers and scheduled tasks calling the old scripts will fail. | Find every reference to run-nifi.bat in services, scheduled tasks and runbooks, and update them to nifi.cmd sub-commands. |
| Python 3.10, 3.11 or 3.12 for Python processors | Optional Python-based processors need one of these Python versions. The NiFi administration guide describes this feature as beta. | Only if you use Python processors, install a supported Python version on each node and confirm the processors are approved for production. |
| flow.xml.gz changed to flow.json.gz | The flow configuration file format changes. Migration is done at the NiFi 1.27.0 step, before moving to 2.0.0. | Complete the flow file migration on 1.27.0 first, and back up the flow file before any upgrade step. |
Five decisions to make before the JDK changes
Each of these decisions sets a default that the Java 21 change will expose, so settle them before any host or image is rebuilt. Several of them depend on platform owners outside the NiFi team, including the people who run JDK patching, configuration management and DNS.
JDK distribution and support policy
NiFi 2 requires Java 21, so the first choice is which Java 21 build your organization will run and who patches it. Ask whether your platform team already has an approved OpenJDK build, how quickly it ships security fixes, and whether your support agreement covers the runtime. Confirm the same build is used in every environment, since a mismatch between staging and production is a common source of late surprises.
Where bootstrap.conf JVM arguments live
Heap size, garbage collector options and other JVM arguments are set in bootstrap.conf, and that file must be consistent across nodes. Decide whether these values are edited per host, managed by configuration management, or baked into a container image. Each option has a different change path, so pick one owner for the file and confirm how changes are reviewed, rolled out and recorded.
IPv6 and host resolution settings
NiFi 2 no longer sets java.net.preferIPv4Stack=true in the default bootstrap configuration, so hosts that resolve names to IPv6 addresses can behave differently after the upgrade. Decide whether to keep IPv4 preference through explicit configuration or to fix name resolution and listener addresses. Confirm with your network team which addresses DNS returns for each node and whether firewall rules and cluster peer addresses use them.
Windows service and nifi.cmd approach
On Windows, NiFi 2.0.0 replaced separate scripts such as run-nifi.bat with nifi.cmd and sub-commands, so any service wrapper, scheduled task or deployment script that calls the old scripts must change. Decide whether NiFi runs as a Windows service through a wrapper your team already supports, or under a different process manager. Confirm the service account, log location and restart behavior with the Windows administrators.
Python processors in or out of scope
The administration guide lists Python 3.10, 3.11 or 3.12 for optional Python-based processors and describes this as a beta feature. Decide early whether any flow depends on them, because that adds a Python runtime, package sources and a separate patch cycle to the host or image. If they are out of scope, confirm that no flow or custom component uses them and that your change process will block them.
How to prepare bare metal, VMs, containers and Windows hosts
On Linux hosts and virtual machines, the work centers on installing a Java 21 runtime next to the existing Java version so the current 1.x service keeps running until cutover. NiFi 2 reads its JVM arguments from bootstrap.conf, so the file must be compared line by line against the new default before any values are carried over. Host resolution also needs review, because NiFi 2 no longer sets java.net.preferIPv4Stack=true by default, and hosts that resolve names to IPv6 addresses may behave differently after the change.
- Backups: Copy the full NiFi home directory, including
conf/,flow.xml.gzorflow.json.gz, the repositories where practical, and thenifi.propertiessensitive properties key stored outside the install. - Configuration to inventory: List every
java.argentry inbootstrap.conf, the JAVA_HOME or service unit setting,/etc/hostsand DNS entries for each node, and any systemd override files. - Side-by-side install: Install the Java 21 build your organization has approved, point a test service unit at it, and confirm that the old and new runtimes do not share a configured path.
- IPv6 and resolution: Test name resolution from each node to every other node and to the ZooKeeper or certificate endpoints, and decide whether IPv4 preference is still needed for your network.
- Pre-cutover test: Start NiFi on a copy of the instance, confirm it reaches the UI or API, reads the flow without errors, and logs no missing-class or unsupported-option messages.
Before cutover, confirm that the test host starts from the same service definition that production will use, not a manually launched command.
For container deployments, the base image must provide a Java 21 runtime, and the entry scripts must start NiFi with the JVM arguments you intend to keep. Image changes are easy to miss because the Java version is often set in the base layer, while the arguments live in a mounted or copied bootstrap.conf. Treat the image as a versioned artifact: build it from a pinned base, record its digest, and test it before any cluster pod or task pulls it.
- Backups: Export the current image digest and tag, the Kubernetes manifests or Compose files, the ConfigMaps and Secrets that hold
nifi.propertiesvalues, and the persistent volumes for repositories and flow storage. - Configuration to inventory: Record the base image, any
JAVA_HOMEorPATHoverrides, thebootstrap.confsource (baked in or mounted), environment variables passed to the entry script, and the health probe paths. - Image rebuild: Rebuild on a Java 21 base, then run
java -versioninside the image and confirm the JVM arguments in the running process match the file you reviewed. - Entry script check: Read the entry script and confirm it does not hard-code paths, script names or flags from the 1.x layout that no longer exist in the NiFi 2 distribution.
- Pre-cutover test: Start a single container from the new image against a copy of the volumes, check the logs for startup errors, and run a probe against the UI or API before rolling it into a cluster.
Confirm with your platform team how the image is scanned and signed, since those steps must run on the rebuilt image as well.
On Windows, NiFi 2.0.0 replaced separate scripts such as run-nifi.bat with a single nifi.cmd that accepts sub-commands. Any scheduled task, service wrapper or deployment script that calls the old batch files will fail until it is updated. Service wrappers also need review, because they usually pass the Java path and JVM arguments directly, which can conflict with the Java 21 install and the bootstrap.conf changes made for NiFi 2.
- Backups: Save the complete NiFi directory, the service wrapper configuration and its registry or XML definition, scheduled tasks, and the sensitive properties key file.
- Configuration to inventory: List every script call (
run-nifi.batand related files), the service account, the JAVA_HOME value, and any wrapper-level JVM settings. - Command mapping: Replace each old script call with the matching
nifi.cmdsub-command, and confirm the sub-commands available in your NiFi 2 release by runningnifi.cmdwithout arguments on a test host. - Service wrapper update: Point the service wrapper at Java 21 and the new startup command, then test install, start, stop and restart from the service manager.
- Pre-cutover test: Start the service on a copy of the instance, confirm the UI loads, check the bootstrap and app logs for errors, and confirm that a stop and restart leave the flow intact.
Ask your Windows administrators to confirm that group policy, antivirus exclusions and firewall rules still apply to the new process path.
Every environment shares a few checks that are easy to skip because they sit outside the NiFi install. These checks cover the Java runtime used by the rest of your estate, third-party JDBC drivers and custom NARs that must load on Java 21, and the monitoring that watches the process. Rebuilding custom code is covered in its own page, but the host must be ready to load those artifacts when they arrive.
- Backups: Keep a record of every JDBC driver jar and custom NAR in the
lib/directories, along with their checksums and source versions. - Configuration to inventory: List the monitoring agents, log shipping rules and backup jobs that reference NiFi paths or process names.
- Runtime compatibility: Confirm with each driver and NAR vendor or maintainer that a Java 21 build exists, and record the version you will load.
- Monitoring and logs: Update process names, log paths and alert thresholds so they match the new startup method.
- Pre-cutover test: Run a full start on a copy of the environment, load a test flow that uses each JDBC driver, and confirm that rollback to the previous host image or service definition works.
Keep the rollback path written down, because it defines how far back you can go if the test host fails.
Checking JDBC drivers and custom NARs before the runtime changes
A flow can look unchanged and still fail after the Java 21 move because the code it depends on is not part of the flow definition. Third-party JDBC driver jars and custom NAR bundles are loaded by the NiFi runtime, so a driver compiled for an older Java release, or one that relies on APIs NiFi 2 no longer exposes, can stop a database processor or controller service from starting even though every processor configuration is correct. Start by building an inventory of every driver jar and NAR in each node's lib and extension directories, recording the file name, version, source, the team that owns it and the flows that reference it. Include bundles that were copied in by hand or pulled from an internal artifact store, since those are the ones most often missing from documentation.
For each entry, decide whether the vendor has confirmed Java 21 support in writing or in a release note. Do not assume that a driver which works on Java 11 or 17 will run on Java 21 without a test, and do not assume that a newer driver release is compatible with your database version. Where the vendor has not confirmed support, record it as an open risk and ask for a supported version before the production window. Ask the vendor whether the driver is still maintained, since an abandoned driver is a poor candidate for a runtime change that will be in production for years.
Test in a staging cluster built on the target Java 21 runtime and the same NiFi 2 release as production, not on a single standalone instance. Confirm that each controller service for a database connection enables, run a test query against a non-production database, and check that every processor that uses the driver starts and processes a sample record set. Then confirm that each NAR loads on every node, because a bundle that starts on one node and fails on another will show up as a disconnected or inconsistent cluster. For code that must change, follow the steps in the sibling topic on rebuilding custom processors and NARs for NiFi 2, and return here to repeat the startup and connection tests on the rebuilt bundles.
Sequence for moving hosts to Java 21 and NiFi 2
This sequence moves each NiFi host from its current runtime to Java 21 and NiFi 2 in an order that keeps a known-good version and a rollback point at every stage. It ends with production nodes restarted in the order the cluster guidance requires.
Freeze flow changes during the move
The platform owner announces a change freeze for flows, parameter contexts and NARs on the affected clusters, and the flow owners confirm that no pending edits will be deployed until the move closes. Record the current NiFi version, Java version and the list of running process groups so the starting state is documented. Check: the change record names the freeze window, the owners who approved it, and the exact starting versions. Rollback point: none is needed yet because nothing has changed on the hosts.
Back up configuration, repositories and keys
Back up the flow configuration file, the flow definition, the conf directory, the sensitive properties key, the keystore and truststore, and the repositories that hold queued data and provenance, following the NiFi Administrator's Guide for each node. Store the sensitive properties key separately from the flow backup, because a flow cannot be read without the key that protects its sensitive values. Check: a test restore of the configuration and key into a scratch directory starts without error on a non-production host. Rollback point: the backup set is the only path back to the current state, so confirm it is complete and readable before continuing.
Inventory NARs and JDBC drivers
List every custom NAR, every third-party JDBC driver and every processor that comes from outside the standard distribution, and record the owner and source build for each. Identify which ones were compiled against the Java runtime and NiFi API versions in use today, since these must be rebuilt or verified for NiFi 2. Check: each item has an owner, a source location, and a status of rebuild, verify or retire. Rollback point: the inventory does not change the running system, so you can stop here and resume later without undoing work.
Upgrade to NiFi 1.27.0 and verify
The migration guidance requires moving to NiFi 1.27.0 before 2.0.0, so upgrade each node to 1.27.0 in staging first, then confirm the cluster forms, flows start, and the restored sensitive properties key decrypts existing values. Run the flows that matter most and compare their queue counts and outputs with the pre-change baseline. Check: all staging nodes connect, every critical flow processes test data with expected output, and no sensitive value shows as unreadable. Rollback point: revert the staging node to the prior 1.x build using the backup set.
Convert the flow file to JSON
Convert the flow configuration from flow.xml.gz to flow.json.gz as described in the migration guidance, and keep the original XML file in the backup set. Review the converted file for process groups, controller services and parameter references that the converter did not carry through as expected. Check: the converted flow loads on the 1.27.0 staging node, and the component count matches the pre-conversion inventory. Rollback point: restore the original flow.xml.gz and the 1.27.0 binaries together.
Install Java 21 and update bootstrap.conf on staging
Install a Java 21 runtime on one staging node, point the NiFi startup configuration at it, and review bootstrap.conf for JVM arguments that need to change. Remove the java.net.preferIPv4Stack=true setting if your hosts are meant to use IPv6 or if you have been relying on it, and confirm that hostnames resolve consistently in both directions. Also note that on Windows, NiFi 2.0.0 replaces separate run scripts with nifi.cmd and sub-commands, so update any service wrappers to match. Check: the node reports the expected Java version at startup, and host resolution returns the same addresses from every node. Rollback point: restore the previous bootstrap.conf and Java path.
Start NiFi 2.0.0 in staging and test flows
Install NiFi 2.0.0 on the staging nodes with the converted flow file and the updated bootstrap configuration, then start the cluster. Address configuration errors caused by renamed or removed components, including the variable registry scope and the renamed distributed map cache components, before running tests. Run the flow and JDBC driver tests against representative data, including custom NARs rebuilt for NiFi 2. Check: every critical flow produces the same outputs as the baseline, each JDBC connection passes its test query, and the cluster shows no unresolved component warnings. Rollback point: return the staging nodes to 1.27.0 with the backup set.
Restart production nodes in cluster order
Restart production nodes one at a time in the order the NiFi cluster guidance requires, with every node running the same version before the flow is resumed. Drain or pause queues where the runbook calls for it, and confirm each node rejoins and reports healthy before the next one is restarted. Check: all nodes show the same NiFi and Java versions, the cluster has no disconnected members, and the flows show the expected throughput after the freeze lifts. Rollback point: if a node fails to rejoin, stop the rollout and restore that node from the backup set, keeping the nodes already upgraded on a version the cluster can run.
What makes the Java 21 move take longer
This table lists the factors that most change how long a Java 21 move takes for a NiFi 2 estate. Read each row as a question to answer about your own environment before you plan the cutover window. The main takeaway is that custom code, third-party drivers and the number of hosts usually matter more than the JDK installation itself.
| Driver | Why it matters | What to confirm |
|---|---|---|
| Custom NARs and their source | Each custom NAR must be rebuilt and retested against Java 21 and NiFi 2 APIs. Source code that no longer exists or has no owner adds the most uncertainty. | How many custom NARs run in production, whether each has source in version control, and who can build and test it. |
| Third-party JDBC drivers | Database drivers loaded into NiFi must run on Java 21. Some vendors certify only older JDK releases, which can block the upgrade for a specific database. | Each driver's vendor, version and written Java 21 support statement, plus any driver used by a controller service. |
| Python processors | Python-based processors are an optional beta feature in NiFi 2 and need Python 3.10, 3.11 or 3.12 on every node that runs them. Hosts with other Python versions need separate work. | Whether any flow uses Python processors, which Python version each node runs, and whether the approved base image includes it. |
| Hosts and container images | Each host and each image needs its own JDK, bootstrap.conf review and test pass. Drift between hosts often causes the most rework. | The total count of hosts and images, how they are built, and whether one pipeline produces all of them. |
| Windows service wrappers | On Windows, NiFi 2 uses nifi.cmd with sub-commands instead of separate scripts. Service wrappers that call the old scripts must be updated and retested. | Whether NiFi runs as a Windows service, which wrapper or scheduler starts it, and who owns that configuration. |
| Number of cluster nodes | Every node must run the same Java and NiFi versions, so the cutover order and rollback plan scale with node count. Mixed-version clusters need a defined window. | Node count, the restart order, queue draining approach and the rollback path for each node. |
| Flows that depend on 1.x-only components | Flows that rely on components removed in NiFi 2 may need replacement before the runtime change makes sense. Those flows often need a separate plan. | How many flows use removed components, where they run, and whether a 1.x island will remain during transition. |
| IPv6 and host resolution | NiFi 2 no longer sets java.net.preferIPv4Stack=true by default, so hosts with IPv6 enabled may need resolution changes that affect cluster and TLS traffic. | Whether hosts have IPv6 enabled, how names resolve between nodes, and whether bootstrap.conf overrides the old default. |
Questions teams ask before the Java 21 upgrade
What does the Java 21 upgrade cost and what drives the fee?
The cost depends on scope, not on the JDK itself, which is free to download. A fixed-scope engagement is priced from a written list of hosts, environments, flows, custom NARs and JDBC drivers to check, plus the testing and cutover work. The main cost drivers are the number of environments (development, test, production and disaster recovery), how many custom processors or NARs must be rebuilt and retested on Java 21, how many third-party JDBC drivers need confirmation, and how much flow regression testing your business requires. Some work recurs, such as patching the JDK and retesting drivers after each NiFi release, while the initial inventory and cutover are one-time. Ask any quote to itemize these components and state what is excluded, such as cluster changes or the separate NiFi 2 migration.
How long does the Java 21 upgrade take?
Duration is set by the size of the estate and the number of change windows you can use, not by the JVM switch alone. Changing the runtime and bootstrap.conf on a single test node can be quick, while a multi-node cluster across several environments needs staged testing, rolling restarts and sign-off from application owners. Custom NAR rebuilds and driver validation often take longer than the host changes because they require test data and regression runs. Ask for a timeline in the written scope that lists each environment, the dependencies on your change board and the points where your team must approve work before the next step.
What must our team provide before the upgrade starts?
Your team provides access, information and approvals. The main inputs are:
- An inventory of NiFi hosts, containers, operating systems and current Java versions
- Access to the NiFi UI, the
bootstrap.conffiles and the deployment tooling in each environment - A list of custom processors, NARs, third-party JDBC drivers and scripted components
- Representative test data and expected outputs for critical flows
- Change windows, rollback approval and named owners for each flow
Without these, the team can only confirm the Java runtime, not whether flows behave the same way. Confirm access rules and data handling for test environments before the first session.
Can our internal team do the Java 21 upgrade alone?
Yes, many teams can, provided they have Linux or Windows administration skills, access to build pipelines and someone who understands each flow's data path. The work is mostly configuration and testing, but it becomes harder when custom NARs need recompilation, when JDBC drivers lack confirmed Java 21 support, or when clusters run in restricted networks. Assess whether your team has capacity for a full regression pass and whether it can handle a rollback at night. A partner is useful when you want a fixed scope, an independent test record or help with several environments at once. Either way, the official System Administrator's Guide is the reference for requirements.
Do we need to upgrade to NiFi 1.27.0 before moving to Java 21?
Java 21 is a runtime requirement for NiFi 2, so the Java change belongs to the NiFi 2 migration rather than a separate step on 1.x. The NiFi migration guidance requires upgrading to NiFi 1.27.0 before moving to 2.0.0, so a 1.x instance must reach that release first. Do not plan a Java 21 change on a 1.x line that is not supported for this path. Confirm the current migration sequence in the migration guidance before scheduling, because the order of changes affects which components you can test on which runtime.
How should we handle IPv6 and host names after the change?
NiFi 2.0 no longer sets java.net.preferIPv4Stack=true in the default bootstrap configuration, so hosts that resolve to IPv6 addresses may behave differently. Check how each node resolves its own name and its peers, both in DNS and in /etc/hosts, and whether any configuration uses IP addresses that the JVM may now report differently. Decide whether to keep IPv4 preference by setting the property explicitly in bootstrap.conf or to fix host resolution. Test cluster communication and TLS endpoints in a non-production environment before cutover, because name mismatches often appear only under load or after restarts.
What changes on Windows when moving to NiFi 2?
On Windows, NiFi 2.0.0 replaced separate scripts such as run-nifi.bat with nifi.cmd, which uses sub-commands. Update service wrappers, scheduled tasks and any deployment scripts that call the old files, and confirm that the Java 21 runtime is the one the service launches. Check your JAVA_HOME and PATH settings, because a service account may still find an older JDK. Test start, stop and status commands on a copy of the host before changing production, and keep the old scripts until your automation has been validated.
What does a rollback look like if the Java 21 change fails?
A rollback returns the host to the previous JDK and the previous configuration files, usually from a backup taken before the change. Keep a copy of bootstrap.conf, the NiFi installation directory and the flow configuration, and record the exact JDK version in use before the change. Confirm with your team whether rollback needs data reconciliation, since queued flow files and repository state may be affected if the node ran on Java 21 for a period. Agree the rollback trigger, owner and time limit in the change plan, and rehearse the steps on a test node before the production window.
How DeployOpen scopes and delivers the NiFi Java 21 upgrade
DeployOpen plans, implements, tests, documents and supports self-hosted open-source platforms inside your own infrastructure, including the hosts and container images that run Apache NiFi 2. For the Java 21 requirement, we start from an inventory of your runtimes, drivers and custom NARs, then deliver a fixed-scope change that your team can operate after handover.
How we scope
- We inventory current JVM versions, bootstrap.conf arguments, hosts and container images across every NiFi node.
- We list third-party JDBC drivers and custom NARs, then confirm which ones need a rebuild or vendor confirmation for Java 21.
- The written scope fixes deliverables, environments and timelines before any change is made to your systems.
How we build
- We select a JDK build with your team against your support policy, then pin it in images and host configuration.
- We review bootstrap.conf and the IPv6 resolution behavior in NiFi 2 against your network design, then test changes in a staging cluster.
- We run flows, JDBC connections and custom NARs in a non-production environment and record the results for your review.
How we hand over
- You receive updated runbooks covering the JDK version, JVM arguments, Windows nifi.cmd usage and rollback steps.
- We document the compatibility list for drivers and custom NARs, including open items that depend on third-party vendors.
- Knowledge transfer sessions walk your operators through the change, so they can repeat the steps on future releases.
How we support
- Ongoing support, upgrades and continuous testing are available as a retainer after the initial change is complete.
- A retainer can cover JDK patch updates, driver re-validation and retesting of custom NARs when NiFi releases change.
- Confirm with DeployOpen the support hours, response expectations and change-control process before signing the written scope.

