Rebuilding custom NiFi processors and NARs for NiFi 2

Custom NARs built for NiFi 1.x usually fail on NiFi 2 at compile, load or runtime. This page lists what your processor code must change and how to test the rebuilt bundles before cutover.

On this page

Why custom NiFi processor rebuilds are the step teams underestimate

If your team runs custom NARs on NiFi 1.x, every one of them must be rebuilt against the NiFi 2 API and tested before cutover, because the 1.x line cannot be carried forward. The NiFi project explains that 1.x cannot be maintained further because it depends on Jetty 9.4, Spring Framework 5.3 and AngularJS 1.8, which cannot be upgraded within that line. Staying on 1.x therefore means running extensions on a platform that will not receive the fixes you need, so the rebuild is a required step rather than an optional cleanup.

The supported path runs through NiFi 1.27.0. The NiFi migration guidance requires upgrading to 1.27.0 before moving to 2.0.0, and it also changes the flow configuration file from flow.xml.gz to flow.json.gz. Teams often plan the custom code work as a single build change, but the work spans the API, packaging, UI and expression language, and each change can break a processor that compiled cleanly before. Treat the NiFi migration guidance as the reference list of changes, and map each one to the classes, resources and flows in your own NARs before estimating the work.

Ask for an inventory before committing to a schedule: every custom NAR, the NiFi version it was built against, its third-party dependencies, and every flow that references its components. Confirm which of those components use removed expression language scopes or deprecated APIs, and which depend on a JDK or servlet stack that must change. A NAR that is only tested against a development instance can pass a build and still fail in a cluster, so plan the test environment as part of the rebuild rather than after it.

Code changes NiFi 2 requires in custom NARs

This table lists the code, build and packaging changes that NiFi 2 asks of custom processor bundles, with the impact of each and the action to take. Read each row as a checklist item for the rebuild, and confirm the exact class names and method signatures against the NiFi 2 API and component documentation before editing code. The main takeaway is that most changes are mechanical, but a missed one can stop a NAR from loading or change how a component behaves.

ChangeImpactAction needed
Java 21 as the minimum runtimeCustom NARs built for older Java targets may fail to load or run on NiFi 2 hosts that use Java 21.Compile and test against Java 21, and confirm the build target and any third-party dependencies support it.
javax.servlet to jakarta.servlet imports (Servlet API 6 from 2.0.0-M2)Code that imports javax.servlet classes will not compile or bind against the NiFi 2 web layer.Replace javax.servlet imports with jakarta.servlet, then check any libraries bundled in the NAR for the same change.
Null no longer accepted in property descriptor defaultValue()Descriptors that pass null as the default value will fail at build or startup.Remove null defaults and use an explicit default value, or omit the default where the API allows it.
additionalDetails.html moved to additionalDetails.md in 2.0.0Component help content in the old HTML file is no longer the file NiFi reads, so help text may be missing.Write the component documentation in additionalDetails.md and confirm the file path inside the NAR resources.
Custom Advanced UIs open at the web application root instead of /configureBookmarks, links or proxy rules that target the /configure path can break for operators.Update links and reverse proxy rules, and confirm the root path behavior in the NiFi 2 Developer's Guide.
VARIABLE_REGISTRY expression language scope removed, replaced by ENVIRONMENT scopeProperty descriptors that declare VARIABLE_REGISTRY scope no longer match the platform, and expressions may not resolve as expected.Change the scope to ENVIRONMENT and test each property that uses expression language with parameter contexts.
Rebuild against the NiFi 2.0 APINARs compiled against 1.x APIs may reference removed or changed classes and will not load correctly.Update the nifi-api and related dependency versions to the NiFi 2.0 API, rebuild every NAR, and confirm the API version in the NiFi component documentation.

How to find every NAR and code path that breaks

Start by listing every custom NAR and the flows that instantiate its processors, controller services and reporting tasks, because a rebuild is only as complete as that inventory. Pull the source for each custom bundle into version control, record its Maven parent and NiFi API version, and list any third-party libraries it packages. Then search the source tree for the patterns the migration guidance names: javax.servlet imports, which must become jakarta.servlet; additionalDetails.html files, which must be converted to additionalDetails.md; defaultValue() calls that pass null; VARIABLE_REGISTRY in expression language scope declarations; and any path or link that assumes the old /configure route for a custom Advanced UI. Each hit is a change to make or a test to write, and the search results should be attached to the change ticket.

Search results alone miss what flows actually do at runtime. NiFi 2 writes the flow configuration to flow.json.gz instead of flow.xml.gz, so take the flow definition from your 1.x environment through the migration path and then load it into the 2.x test cluster. Once it loads, check every processor and controller service that comes from a custom NAR for invalid or missing state, since a component can load in a stopped or invalid condition when its properties or scope no longer match. Also confirm that any expression language reference to a variable still resolves, because a flow that references a removed scope will not fail at load time in a way that is obvious to operators.

Treat the flow check as a list of confirmations rather than a pass-fail count. Ask the team that owns each NAR to confirm the Java 21 build target, the Servlet 6 dependency set and the test coverage for each property descriptor. Confirm with the flow owners which processors feed production data paths, because those are the ones that need a replay test against sample data before cutover. The NiFi migration guidance and the deprecated components documentation are the reference for the exact change list, so verify each item against the version you are targeting rather than relying on memory of an earlier release.

What to prepare before rebuilding NARs

Rebuilding custom NARs against the NiFi 2 API is mostly a preparation exercise. The six items below decide whether you can tell a compile fix from a behavior change, and whether you can roll back if a rebuilt bundle misbehaves in a cluster.

Source inventory and build baseline

List every custom NAR, its source repository, the NiFi version it was built against, and every processor, controller service and Advanced UI it contains. Record the current build tool, dependency versions and any shaded libraries. Build the unchanged 1.x source once and keep that output as the baseline, so later failures can be traced to your code changes rather than to a drifting toolchain or a dependency that moved while you were preparing.

NiFi 2 build and test environment

Stand up a build host or CI runner on the Java 21 runtime that the NiFi administration guide lists as the minimum, and compile against the NiFi 2 API rather than the 1.x API. Pin the JDK build and the Maven or Gradle plugin versions. Confirm that your build fails on the javax.servlet imports and the removed variable registry scope so you know the compiler is checking what you expect.

Production flow copy and sample data

Export the flows that use each custom component, then take a sanitized copy of production flow definitions and a representative sample of input data, including edge cases such as malformed records, large payloads and duplicates. Use these for regression runs. Keep sensitive values out of the copy, and confirm that the flow definitions you test in a NiFi 2 instance are the same ones that run in production, so results reflect real configurations.

Version control for NAR source

Place each custom extension in a Git repository with tagged 1.x release points, a branch for the NiFi 2 port, and a documented build command that anyone on the team can run. Record which commit produced each NAR artifact and its checksum. This history lets you compare behavior between versions, reproduce a build for audit, and tell the team exactly which code is running in each environment.

Named owners for behavior changes

Assign an owner for each custom component who can approve any change in observable behavior, such as altered property validation, changed output attributes, different record handling or new Markdown documentation. Agree in advance who reviews deprecated API replacements and who accepts a difference in test results. Without named owners, compile fixes tend to merge quietly, and a changed default only appears after data has already flowed through production.

Rollback copy of 1.x NARs

Keep the built 1.x NAR files, their checksums and the matching flow definitions in a controlled artifact store before any cluster change. Confirm that you can redeploy them to the 1.x instance without rebuilding from source. This matters most when you run a mixed estate during migration, because a rollback that depends on a rebuild can take longer than the window you planned for the cutover.

How rebuild work differs by component type

Custom processors are the most common rebuild target and usually the first to fail compilation. NiFi 2.0.0-M2 moved from Servlet API 3 to Servlet API 6, so any code that imports javax.servlet must switch to jakarta.servlet. Descriptor logic also changed: passing null to a property descriptor's defaultValue() is no longer supported, so defaults must be explicit values. Processors must also be compiled against the NiFi 2.0 API and built on Java 21.

  • Servlet imports: replace every javax.servlet reference, including indirect uses through helper libraries.
  • Descriptor defaults: remove any defaultValue(null) calls and set an explicit value or leave the default unset.
  • Expression language scope: drop any use of the VARIABLE_REGISTRY scope and move references to parameter contexts or ENVIRONMENT.
  • Build target: compile against the NiFi 2 API and Java 21, not the 1.x baseline.
  • Additional details: move documentation from additionalDetails.html to additionalDetails.md.

Retest each processor against a flow that exercises every relationship, property validation path and expression language configuration, and confirm the NAR loads with no missing class errors on a clean NiFi 2 node.

Rebuild and test sequence for custom NARs

This sequence turns custom NiFi processor code into tested NARs that run on NiFi 2, with a clear check and rollback point at each stage so a failed rebuild never reaches the production cluster. It ends with NARs staged for cluster cutover.

  1. Pin the NiFi 2 API target

    The developer sets the nifi-api and nifi-framework dependency versions in the Maven build to a NiFi 2.x release, selects the Java 21 compiler target, and records the chosen version in the project's build notes. The team confirms which 2.x release the test node will run so the NAR is built against the same API it will load under. Check: a clean build with the pinned version compiles without falling back to 1.x artifacts. Rollback: keep the 1.x branch and build tags untouched so the original NAR can be rebuilt at any time.

  2. Fix imports and property descriptors

    The developer replaces every javax.servlet import with the jakarta.servlet equivalent, which NiFi 2.0.0-M2 and later require after the move to Servlet API 6. In the same pass, each PropertyDescriptor that passed null to defaultValue() is changed to omit the call or supply a real default. Check: a compile with warnings treated as errors passes, and a grep for javax.servlet and defaultValue(null) returns no hits in main or test code. Rollback: revert the commit that contains the import and descriptor changes, which should be isolated from behavior changes.

  3. Move additional details to Markdown

    Component documentation moves from additionalDetails.html to additionalDetails.md in NiFi 2.0.0. The developer converts each file, keeps the same resource path under the component's package, and checks that the rendered help text still describes the current property names and relationships. Check: the NAR's docs folder contains the .md file and the processor help opens in a test build without a missing-document error. Rollback: keep the original HTML files in version control until the Markdown version has been reviewed.

  4. Remove VARIABLE_REGISTRY expression language scope

    The developer finds every property that declares the VARIABLE_REGISTRY expression language scope and changes it to a scope NiFi 2 supports, normally FLOWFILE_ATTRIBUTES or ENVIRONMENT where the value is read from the environment. Values that were previously sourced from variable registry entries are reviewed with the flow owner so they can move to parameter contexts. Check: a search for VARIABLE_REGISTRY in the source returns nothing, and unit tests that resolve expressions pass. Rollback: restore the previous descriptor set on the branch, since the change alters how property values are resolved.

  5. Build and run unit tests

    The developer runs the Maven build with the NiFi test harness, covering processor validation, relationship routing, property validation and any controller service mocks. The team reviews failing tests and adds cases for the changes made in earlier steps, such as jakarta servlet handlers and expression language resolution. Check: the build produces a NAR file, the NAR manifest shows the expected NiFi API dependency, and all unit tests pass. Rollback: if a test cannot be fixed without changing behavior, tag the commit and hold the NAR out of the test node until the cause is understood.

  6. Deploy to a NiFi 2 test node

    The team copies the NAR into the lib directory of a NiFi 2 test node that matches the target release and Java 21 runtime, then loads a copy of the production flow converted to the flow.json.gz configuration format. The migration guidance requires that flow file format for NiFi 2, so the conversion must be completed before this step. Check: the node starts, the custom processor appears in the component list without a missing-component warning, and the flow validates. Rollback: remove the NAR from the lib directory and restart the node with the previous flow file, which is retained from the 1.x instance.

  7. Run flow regression tests with provenance comparison

    The flow owner feeds a fixed set of representative inputs through the flow on the 1.x instance and the NiFi 2 test node, then compares output content, attributes, routing relationships and provenance event types for each run. Differences in attribute values, dropped events or changed routing are logged and traced to the custom processor or to the NiFi 2 changes. Check: every expected output matches or each difference has a documented, accepted cause. Rollback: keep the 1.x flow running in production and return the test node to the previous NAR until differences are resolved.

  8. Confirm custom UI paths

    If the NAR includes a custom Advanced UI, the team confirms that it opens at the web application root in NiFi 2 rather than at the /configure path used in earlier releases. Links, bundled scripts and any hard-coded URLs in the UI are updated to match, and the team checks that the UI loads for a user with the expected authorization. Check: the Advanced UI opens from the processor configuration dialog on the test node and its API calls succeed. Rollback: restore the previous UI routes in a separate build if the change cannot be completed in time.

  9. Stage NARs for cluster cutover

    The team publishes the verified NAR, its checksum, the build version and the test evidence to the artifact store used for deployments, and records the exact NiFi 2 release each NAR was built against. The cluster upgrade plan then references these artifacts so every node receives the same NAR during cutover. Check: each node in the staging inventory has the matching NAR checksum and a signed-off regression report is attached to the change record. Rollback: keep the 1.x NARs available in the artifact store and the previous NiFi 1.x installation ready until the cutover is accepted.

How to test rebuilt NARs before cutover

Testing a rebuilt NAR has to cover more than whether it compiles. Start with compile and unit tests against the NiFi 2 API, then load the packaged NAR on a NiFi 2 instance and confirm every custom processor, controller service and property descriptor appears without errors in the bulletin board and the component list. A NAR that builds cleanly can still fail at load time because of a leftover javax.servlet import or a property descriptor that passes null to defaultValue(), so the load check is the first gate that catches what the compiler does not. Keep the unit tests focused on logic, and add a test for each property descriptor that exercises its validators and default values under the NiFi 2 rules.

The most useful layer is a flow-level regression against the 1.x baseline. Run the same representative input through the old flow on 1.x and the rebuilt flow on NiFi 2, then compare output content, FlowFile attributes and provenance event types and counts for each custom component. Differences in attribute names, routing relationships or event sequences are usually the first sign of a changed default or a removed expression language scope, so record them as defects rather than accepting them as expected. Include the UI check here as well: open each custom Advanced UI at the web application root rather than /configure, and confirm that its configuration saves correctly and its additional details render from additionalDetails.md. Confirm the exact behavior of your own components with the NiFi 2 Developer's Guide and the NiFi migration guidance before you write expectations.

Load tests on representative data come last, using volumes and record shapes taken from production rather than synthetic samples. Measure throughput, error rates and memory use of the rebuilt NAR under the same settings the 1.x flow used. Every run, including the Java 21 runtime version, the NAR build identifier and the NiFi 2 release, must use the same Java 21 runtime as production, because results from a different JDK do not prove anything about the target. Record each test layer's inputs, outputs, pass or fail decisions and open defects in a sign-off record that the component owner and the operations team both approve before cutover. Ask your quote to include this record as a deliverable, and confirm with your own change process which evidence it must contain.

What makes NAR rebuilds take longer

This table compares the factors that change how long a custom NAR rebuild takes for NiFi 2. Read each row as a question to answer about your own extensions before estimating effort. The main takeaway is that the count of components matters less than how deeply each one depends on removed APIs, variable registry expressions and missing tests.

DriverEffect on effortWhat to check
Number of custom processors and controller servicesEach component needs its imports, descriptors and tests reviewed, so effort grows with the countInventory every processor and controller service in your NARs and note which ones your flows use
Use of VARIABLE_REGISTRY in expressionsExpressions that rely on the removed scope must be rewritten, and the work spreads into flows and parameter setupSearch property descriptors and expression definitions for the VARIABLE_REGISTRY scope and map each use to an ENVIRONMENT or parameter replacement
Custom Advanced UIsUI assets served from the old /configure path must be moved to the new root path and retested in the browserConfirm which components ship Advanced UIs and check their paths, scripts and API calls
Depth of Servlet or Jetty codeMoving from javax.servlet to jakarta.servlet touches every class that handles HTTP, and Jetty-specific code may need more changesFind all javax.servlet imports and any direct Jetty references, then confirm which handlers are part of the extension
Third-party libraries that must support Java 21A library without a Java 21 compatible release can block the build or force a replacement, which adds vendor and design workCheck the version of every bundled dependency and confirm Java 21 support with each library maintainer
Missing or outdated source and testsWithout source or tests, changes cannot be verified and behavior changes can go unnoticed, which lengthens validationConfirm you hold buildable source, the original build configuration and automated tests for each NAR
Flows that depend on the componentsEvery flow using a rebuilt component needs a regression run, and flows with unusual settings take longer to validateList the process groups and templates that reference each NAR and plan a test run against each one in a non-production cluster

Questions teams ask about rebuilding NiFi custom NARs

How much does rebuilding custom NiFi NARs cost?

No supplied figure sets this cost, and the quote depends on the written scope. The main cost drivers are how many custom processors, controller services and UI components you have, how many use APIs that changed, how much of the code relies on the removed VARIABLE_REGISTRY scope or null property defaults, and how much testing the flows need. Ask for a quote that separates the code changes, the build and packaging work, the test plan, and any cutover support. Most of this is one-time work, while rebuilding after each future NiFi release is a recurring cost to plan for.

How long does a NAR rebuild take?

Duration depends mainly on the number of extensions, how far they depart from the NiFi 2 API, and how many flows depend on them. Teams with a small set of processors that use standard APIs usually finish code changes faster than teams with large bundles that use the Servlet API, custom UIs or scripted logic. Testing often takes longer than the code changes because each flow must run against realistic data. Ask for a timeline in the written scope that lists the milestones and the internal reviews it depends on.

What does the internal team need to provide for a NAR rebuild?

Plan to provide three things: access to the current source code and build files, representative test data that reflects real record formats and edge cases, and named flow owners who can confirm expected behavior. Source access lets engineers find imports and property descriptors that need changes. Flow owners confirm which processors are used, which properties are set and which outputs matter. Without test data and flow owners, it is hard to show that a rebuilt NAR behaves the same as the original.

Can our own team rebuild the custom NARs without outside help?

Yes, if the team has Java developers who know the NiFi Developer's Guide, can work with Maven builds, and can run the flows in a non-production NiFi 2 environment. The work is usually manageable for a small number of extensions with standard APIs. The risk grows with large bundles, unfamiliar third-party dependencies or many production flows. Decide based on available time, familiarity with the NiFi 2 API changes in the migration guidance, and the cost of a failed cutover.

Can a NAR rebuilt for NiFi 2 run on NiFi 1.x?

Do not plan on it. The NiFi 2 API changes the Servlet imports to jakarta.servlet, removes null defaults in property descriptors, and changes the expression language scope, so a NAR built against the NiFi 2 API is not designed to run on NiFi 1.x. The 1.x line also cannot be maintained further because it depends on Jetty 9.4, Spring Framework 5.3 and AngularJS 1.8, which the project says cannot be upgraded in that line. Keep the original 1.x NARs for the legacy environment and confirm compatibility with the project's documentation for your exact versions.

What happens to a custom component that is only used in a removed component's flow?

The custom NAR may still be valid, but the flow around it may not be. If a custom processor depends on a service such as a removed component, you need to replace or remove that dependency before the NAR can work in NiFi 2. Start by listing every flow that references the custom component and every removed component it connects to. Then decide whether to rebuild the custom code against a replacement, move the logic into a supported processor, or retire the flow. This decision should be made with the flow owners before the rebuild begins.

What should we check after rebuilding a custom NAR?

Check that the NAR loads in a NiFi 2 test instance, that every processor and controller service appears with the expected properties, and that the Markdown additional details render. Then run each flow with the test data and compare outputs, provenance events and error routes against the 1.x baseline. Confirm that expression language uses the ENVIRONMENT scope where it previously used the variable registry, and that any custom Advanced UI opens at the web application root. Record the results so the change can be reviewed.

How to keep a rollback path during NAR cutover

Keep the working 1.x NARs, the 1.x flow files and a full copy of the 1.x configuration untouched until the NiFi 2 cluster has passed regression on your custom processors. Treat the 1.x installation as the fallback, not as a directory you clean up after the first successful run. Store the rebuilt 2.x NARs in a separate extensions directory and do not overwrite the 1.x set in place, so that a bad deployment can be reversed by pointing the node back at the old artifacts. Confirm with your own change records that each custom NAR has a known source revision and a checksum for both the 1.x and 2.x builds.

Rollback is a restore operation, not a configuration switch. NiFi 2 changes the flow configuration file from flow.xml.gz to flow.json.gz, as the migration guidance requires, so a 2.x node that has written its flow cannot simply be started again on 1.x with the old file alone. Before cutover, take a backup of the 1.x flow.xml.gz, the conf directory, the flow repositories and the sensitive properties key, and confirm with the NiFi migration guidance how the 2.x upgrade rewrites the flow. Rehearse the restore on a non-production copy so that the time it takes is known before it is needed.

Record which NAR build runs on which node, and keep that record current during the rollout. A simple inventory that lists each node, the NiFi version, the JDK version and the checksum of every custom NAR in the extensions directory is enough for a regression review and for an incident responder. Compare the inventory against the cluster view after each node restarts, because a single node left on an old NAR can produce results that look like a flow defect. Ask your NAR build pipeline to publish these checksums automatically so that the record is generated, not typed.

How DeployOpen scopes and delivers NAR rebuilds

DeployOpen plans, implements, tests and documents custom NiFi processor and NAR rebuilds inside your own infrastructure, starting from a written scope. The work is agreed before it begins, and the rebuilt extensions are handed over with the test evidence your team needs to run them.

How we scope

  • Inventory every custom NAR, its processors, controller services and the NiFi 1.x API calls it uses.
  • Record which flows reference each extension and which expression language scopes they depend on.
  • Agree the written scope, deliverables and timeline before any code changes start.

How we build

  • Move javax.servlet imports to jakarta.servlet and remove null defaultValue() calls from property descriptors.
  • Convert additionalDetails.html to additionalDetails.md and move custom Advanced UI paths off /configure.
  • Build against the NiFi 2 API on Java 21, replacing any VARIABLE_REGISTRY scope with ENVIRONMENT-based designs.

How we hand over

  • Deliver rebuilt NARs with source changes, build instructions and a record of each API change made.
  • Provide test results from a non-production NiFi 2 instance, including provenance and flow-level checks.
  • Document the rollback path and the deployment steps your team needs to repeat the rebuild.

How we support

  • Engagements are fixed-scope, so changes after sign-off are priced through a written change request.
  • Ongoing support, upgrades and continuous testing for custom extensions are available as a retainer.
  • Ask for the support boundaries, response expectations and retainer terms in the written quote.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.