Back to blog

// OSSeva Blog

Migration

Upgrading Apache NiFi 1.x to 2.0: The Sequence, What Breaks, and How to Scope It

Matt Reynolds11 min read

Start here: you cannot go directly to 2.0

Apache NiFi's migration guidance is explicit: migrating to 2.0.0 requires upgrading to 1.27.0 first. The earlier milestone builds had the same shape — 2.0.0-M1 required 1.24.0. If you are on 1.19 or 1.23, your upgrade is two production changes, not one, and the first of them needs validating in its own right.

The reason is practical rather than bureaucratic. The late 1.x releases carry the deprecation logging and the flow-format handling that make the jump possible. Going through 1.27 or later is how NiFi tells you, before the cutover, exactly which parts of your canvas will not survive.

What NiFi 2.0 changed

NiFi 2.0.0 was tagged on 2 November 2024. The final 1.x release, 1.28.1, followed on 19 November 2024, and nothing has shipped on 1.x since. The changes below are from the project's own migration guidance.

Area1.x2.xWhat it means for you
Java8, 11, later 1721 requiredA JVM migration on every node, plus any custom NARs rebuilt
Flow storageflow.xml.gzflow.json.gzProperties that reference the XML file must change; tooling that parses the XML breaks
VariablesVariable registryRemoved — VARIABLE_REGISTRY scope goneEvery variable must become a parameter context before the move
TemplatesSupportedRemovedExport to flow definitions or NiFi Registry first
Servlet APIjavax.servletjakarta.servletCustom UIs and NARs compiled against javax will not load
Cache servicesDistributedMapCacheServer / ClientRenamed MapCacheServer / ClientFlows referencing the old names need updating
ComponentsMany deprecatedDeprecated components removedProcessors on your canvas may simply not exist

The inventory comes before the plan

The single most useful thing you can do before estimating this project is to list every component type on the canvas and count them. It takes minutes and it converts the project from a guess into a gap analysis.

# Every component class on the canvas, across all process groups, by frequency.
# Reads the flow file directly, so it covers nested groups the REST API
# would make you walk one at a time.
zcat conf/flow.xml.gz | grep -o '<class>[^<]*</class>' \
  | sed 's/<[^>]*>//g' | sort | uniq -c | sort -rn

# Anything still using variables rather than parameters
zcat conf/flow.xml.gz | grep -c '<variable '

# Templates that will not exist after the move
zcat conf/flow.xml.gz | grep -c '<template 

Cross that list against NiFi's Deprecated Components and Features documentation. What falls out is three piles: components that carry over untouched, components with a documented replacement, and components with no equivalent that you will have to redesign around. The third pile is your actual project. It is usually smaller than feared and never zero.

A sequence that works

  1. Get to 1.27 or 1.28 first. Treat it as a real release with its own validation. Turn on deprecation logging and read it.
  2. Convert variables to parameter contexts while still on 1.x. This works on 1.x, so you can do it incrementally and validate as you go rather than during the cutover.
  3. Move templates into NiFi Registry or flow definitions. Same logic — do it where it is reversible.
  4. Replace deprecated processors on 1.x wherever a replacement exists there too. Many do. Each one you swap early is one fewer unknown on the day.
  5. Rebuild custom NARs against the 2.x API and Java 21. The javax to jakarta change catches custom UIs in particular.
  6. Stand up 2.x in parallel and replay real data through it. NiFi's output is the contract. Compare what each version produces from the same input before anything downstream depends on it.
  7. Cut over by flow, not by cluster, if your topology allows it.

Steps two to four are the ones that get skipped, and they are the ones that turn a manageable migration into a long weekend.

Where these projects go wrong

  • Underestimating the Java move. Java 21 is not only a NiFi concern. It reaches every custom processor, every JDBC driver and every library your scripted processors load.
  • Scripted processors. ExecuteScript bodies are code that nobody inventoried because they live inside the flow rather than in a repository. They need reading, not just migrating.
  • Downstream assumptions. Record handling and type behaviour have changed in places — the project's guidance notes, for example, that a RecordPath function now returns a differently typed field than before. A consumer that tolerated the old output may not tolerate the new one.
  • Treating it as an infrastructure task. It is a data-correctness task with an infrastructure component.

If you cannot start yet

Most teams reading this are not about to begin — they are trying to find out how big the problem is. In the meantime the 1.x line receives no fixes, and NiFi holds the credentials for every system on its canvas, which makes an unpatched instance a more serious exposure than its role as “plumbing” suggests.

That gap is what OSSeva covers: patched 1.x builds with the canvas, the NAR set and the parameter contexts untouched, so the migration can be scoped from a real inventory instead of being rushed by a finding. We will also tell you plainly if your canvas is simple enough that you should just migrate.

Related

Tags

Apache NiFiMigrationNiFi 2.0Upgrade

Ready to get your open source under control?

Talk to an OSSeva engineer about CVE coverage, compliance, and migration support for your stack.