// OSSeva Blog
MigrationUpgrading Apache NiFi 1.x to 2.0: The Sequence, What Breaks, and How to Scope It
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.
| Area | 1.x | 2.x | What it means for you |
|---|---|---|---|
| Java | 8, 11, later 17 | 21 required | A JVM migration on every node, plus any custom NARs rebuilt |
| Flow storage | flow.xml.gz | flow.json.gz | Properties that reference the XML file must change; tooling that parses the XML breaks |
| Variables | Variable registry | Removed — VARIABLE_REGISTRY scope gone | Every variable must become a parameter context before the move |
| Templates | Supported | Removed | Export to flow definitions or NiFi Registry first |
| Servlet API | javax.servlet | jakarta.servlet | Custom UIs and NARs compiled against javax will not load |
| Cache services | DistributedMapCacheServer / Client | Renamed MapCacheServer / Client | Flows referencing the old names need updating |
| Components | Many deprecated | Deprecated components removed | Processors 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
- 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.
- 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.
- Move templates into NiFi Registry or flow definitions. Same logic — do it where it is reversible.
- 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.
- Rebuild custom NARs against the 2.x API and Java 21. The javax to jakarta change catches custom UIs in particular.
- 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.
- 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
- Apache NiFi 1.x end of life
- Apache NiFi extended support
- Apache ZooKeeper — clustered NiFi elects its coordinator through it
Tags
Related articles
Ready to get your open source under control?
Talk to an OSSeva engineer about CVE coverage, compliance, and migration support for your stack.