Upgrading from JetPack 5 to JetPack 6: what breaks and how to fix it
The JetPack 5 to JetPack 6 upgrade is a bigger jump than a version number suggests. The kernel moves from 5.10 to 5.15, the container runtime changes, and several BSP APIs that were stable in JetPack 5 are deprecated or removed. What breaks depends on how much custom BSP work your product has accumulated.
Key Insights
- JetPack 5 to 6 is a full platform jump: Ubuntu 20.04 → 22.04, CUDA 11.4 → 12.6, cuDNN 8 → 9, TensorRT 8 → 10, kernel 5.10 → 5.15
- OTA from JP5 to JP6 is not supported, reflash is required
- Everything compiled against JP5 must be rebuilt: TRT engines, camera drivers, kernel modules, Python environments
- Custom camera drivers need porting, the
tegracamsensor API changed between L4T R35 and R36 - Xavier-series modules (AGX Xavier, Xavier NX) are not supported in JetPack 6, JP5.1.x is the end of the line for Xavier
JetPack 5 to 6 is a platform upgrade, not a package update
The version bump from 5 to 6 understates what changed. The full platform delta:
| Component | JetPack 5 (L4T R35) | JetPack 6 (L4T R36) |
|---|---|---|
| OS | Ubuntu 20.04 | Ubuntu 22.04 |
| Kernel | Linux 5.10 | Linux 5.15 |
| CUDA | 11.4 | 12.6 |
| cuDNN | 8.x | 9.x |
| TensorRT | 8.x | 10.x |
| Python (default) | 3.8 | 3.10 |
| OpenCV (bundled) | 4.5.4 | 4.8.1 |
| GStreamer | 1.16 | 1.22 |
This means OTA from JP5 to JP6 is not supported. You cannot apt upgrade your way there. Reflash is required. Teams that try OTA hit A/B slot errors or partial upgrades that leave the system unbootable.
Also worth knowing: JP6 dropped support for Xavier-series modules (AGX Xavier, Xavier NX). If you’re on Xavier, JP5.1.x is your last JetPack.
What still works on JetPack 6 without changes
Before the break list, here is what typically survives the migration intact. Teams that focus only on what breaks underestimate how much they do NOT need to rebuild.
Works without changes:
- Most GStreamer pipelines — GStreamer 1.22 is backwards-compatible with 1.16 for core hardware elements (nvvidconv, nvv4l2decoder, nvv4l2h264enc, nvarguscamerasrc)
- Docker containers that use only userspace libraries — CUDA is mapped in from the host runtime; containers that don’t bundle kernel-dependent code work fine
- Application code that doesn’t link CUDA directly — pure Python, web servers, business logic, REST APIs, database code
- USB peripherals and Ethernet — no driver changes for standard peripherals
- I2C, SPI, UART on standard carrier board pins — the pinmux and driver stack for standard interfaces is stable
- Most apt-installable packages — Ubuntu 22.04 repos cover the same packages as 20.04 with updated versions
The break list is real, but it is scoped. If your JP5 system has no custom camera drivers, no TRT engines, and no code compiled against CUDA 11 directly, the migration is closer to a 1–2 day effort than a 2-week project.
The complete break list when upgrading JetPack 5 to JetPack 6
Go through this before you start. Every item here has caused a blocked migration in the field.
1. CUDA-compiled binaries
Any binary compiled against CUDA 11.4 will not run on CUDA 12.6 without recompilation. This includes your own code and any third-party libraries you built from source. apt-installed NVIDIA libraries will update automatically, but binaries in /opt/, /usr/local/, or your home directory won’t.
Audit: grep -r "libcuda" /opt /usr/local ~/.local 2>/dev/null | grep ".so"
2. cuDNN 8 applications
JetPack 6 ships libcudnn.so.9. Any application that dynamically links libcudnn.so.8 will fail with error while loading shared libraries: libcudnn.so.8: cannot open shared object file.
Options: recompile against cuDNN 9, or install cuDNN 8 from the NVIDIA archive alongside 9 (not recommended long-term, but buys time during migration).
3. TensorRT engines
TensorRT serialized engines are not portable across TRT versions. Every engine built on JP5 (TRT 8.x) must be regenerated on JP6 (TRT 10.x). This is not optional, attempting to load a TRT 8 engine in TRT 10 will crash at deserialization.
Additionally, TRT 10 removed several deprecated APIs from TRT 8. If your code uses IPluginV2 directly or the legacy calibrator interfaces, it will fail to compile.
4. PyTorch and TorchVision
The JP5-compatible PyTorch wheels (CUDA 11.4 builds) are incompatible with JP6’s CUDA 12.6. You need the JP6-specific wheels from NVIDIA’s PyPI or the Jetson Containers project. The version numbers don’t always match what you’d install from pip on a desktop, always use the Jetson-specific builds.
5. Custom camera drivers
This is the hardest one. L4T R36 made changes to the V4L2 subdev framework and the tegracam sensor driver API. A camera driver that works perfectly on JP5 will often fail to compile on JP6, and even if it compiles, behavior differences in the capture subsystem may cause runtime failures.
Specific things that change:
- Sensor driver registration APIs in
tegracam_core - NVCSI configuration interfaces
- The
mclkclock handling changed in R36
We cover this in more depth in the section below.
6. Out-of-tree kernel modules
The kernel version changed from 5.10 to 5.15. Any out-of-tree kernel module (.ko file) built for L4T R35 will fail to load on R36 with ERROR: could not insert module: Invalid module format. All kernel modules must be rebuilt against the L4T R36 kernel headers.
7. Device tree changes on custom carrier boards
L4T R36 updated the reference DTS files significantly. If you have a custom carrier board DTS that was derived from JP5 reference files, it needs an audit before JP6. Known breaking changes:
- DWC3 USB controller:
refclock became mandatory (see our DWC3 error -71 post) - PCIe clock references changed on some Orin variants
- UART/SPI/I2C pinmux configurations may need revalidation
- ODMDATA format changes for some carrier board profiles
8. GStreamer plugin compatibility
GStreamer moved from 1.16 to 1.22. Most pipelines work without changes, but some NVIDIA-specific elements (nvv4l2decoder, nvarguscamerasrc) had interface changes. Pipelines that rely on deprecated property names or pad caps negotiation behavior from 1.16 may need updating.
9. Package names and Python environment
The Ubuntu 22.04 jump means some package names changed (python3-dev → same, but libpython3.8-dev is no longer default, etc.). virtualenvs built against Python 3.8 need to be recreated. Anything using distutils directly will break since it was removed in Python 3.12 (not relevant here) but setuptools behavior changed in 3.10.
Camera driver porting from JetPack 5 to JetPack 6
This is the part most teams underestimate. If you have a custom CSI camera driver, plan for 2–5 days of porting work depending on how much the driver deviates from the NVIDIA sensor driver template.
The main changes in L4T R36 that break JP5 camera drivers:
tegracam API changes. The tegracam_device and tegracam_ctrl_ops structures changed. Functions that were called directly in R35 are now wrapped or renamed. Drivers built against the R35 headers will hit compile errors in tegracam_core.h.
MCLK handling. The sensor mclk clock acquisition changed. In R35, many drivers called clk_get directly. R36 moved this into the framework. Drivers that manage the mclk themselves need the clock handling rewritten.
V4L2 subdev pad config API. The v4l2_subdev_pad_ops structure had members renamed in newer kernel versions included in R36. This causes compile errors that look unrelated to camera bring-up but are.
The fastest path: take the NVIDIA reference sensor driver for a similar sensor (the IMX219 or IMX477 reference drivers in the JP6 source tree), diff it against the JP5 version, and apply the same structural changes to your driver. Don’t try to patch your JP5 driver forward blindly.
For reference on the full camera bring-up process in JP6, see our CSI camera driver bring-up post.
ML stack and TensorRT migration
Rebuilding the ML stack in sequence matters. Do it in this order to avoid dependency conflicts:
- Flash JP6 and boot clean
- Install CUDA 12.6 + cuDNN 9 from the JP6 image (they come pre-installed)
- Install JP6-specific PyTorch wheels (from NVIDIA’s Jetson PyPI or
dusty-nv/jetson-containers) - Install TorchVision matching your PyTorch version (check the Jetson Containers compatibility matrix)
- Re-export ONNX models from your training framework
- Rebuild TensorRT engines on the target with
trtexecor your engine builder
Do not try to install desktop PyTorch wheels. The pip install torch from PyPI will attempt to download CUDA 12 wheels but they are x86 builds and will fail or silently install wrong. Use dusty-nv/jetson-containers for pre-built, verified JP6-compatible PyTorch and TorchVision wheels, it’s the most reliable source for the Jetson ML stack.
NVIDIA’s official JetPack 6 release notes document the full package delta and known issues for each point release.
Step-by-step migration checklist
Use this sequence to minimize the chance of a blocked migration:
Pre-migration (on your JP5 system):
lsmod, record all loaded kernel modules; every.kowill need to be rebuilt- List all virtualenvs and their Python package requirements
- Find all TRT engines:
find / -name "*.engine" 2>/dev/null - Grep for hardcoded CUDA 11 paths:
grep -r "cuda-11\|cuda/11" /opt /usr/local 2>/dev/null - Record your camera driver source location and confirm you have the source, not just the
.ko - If you have a custom DTS, save a copy and note which JP5 reference DTS it was derived from
Post-flash (on JP6):
- Verify CUDA 12.6:
nvcc --version - Verify cuDNN 9:
dpkg -l libcudnn9-dev - Rebuild all out-of-tree kernel modules against L4T R36 headers
- Port and test camera drivers (biggest time sink, start here)
- Recreate Python environments with Python 3.10
- Install Jetson-specific PyTorch and TorchVision
- Re-export ONNX models and rebuild TRT engines
- Run your application’s full test suite before returning the device to service
How long does a JetPack 5 to JetPack 6 migration take?
From projects we have scoped and completed, here are realistic timelines:
| System profile | Estimated time |
|---|---|
| No custom drivers, no TRT engines, no CUDA-compiled code | 1–2 days |
| Custom Python/ML stack, needs PyTorch rebuild and TRT engine regen | 2–4 days |
| One custom CSI camera driver needing port to R36 tegracam API | 3–6 days |
| Multiple custom camera drivers + custom carrier board DTS | 5–10 days |
| Custom kernel modules (not camera) needing rebuild for 5.15 | Add 1–2 days |
The tegracam API port for camera drivers is the single most variable item. A driver that closely follows the NVIDIA reference template (IMX219, IMX477 structure) ports in 1–2 days. A driver with non-standard clock handling, custom NVCSI configuration, or heavily patched register sequences can take 4–5 days.
TRT engine regeneration time depends on model complexity and whether your ONNX export pipeline is already scripted. If you have to re-export from a training framework first, add that to your estimate.
Migrating Docker containers from JetPack 5 to JetPack 6
Containers that use only userspace CUDA libraries (libcuda.so, libcudart.so) work on JetPack 6 without rebuilding, because the NVIDIA container runtime maps the host’s libraries into the container at run time.
Containers that will need rebuilding:
- Containers that bundle PyTorch built against CUDA 11.4 (incompatible with CUDA 12.6 host)
- Containers that load kernel modules (.ko files) — these always use the host kernel, not a container version
- Containers that hardcode
/usr/local/cuda-11paths
To test whether a JP5 container works on JP6 before rebuilding:
# Check what CUDA version the container sees
docker run --runtime=nvidia --rm your-image:tag nvcc --version
# Check library loading
docker run --runtime=nvidia --rm your-image:tag ldconfig -p | grep cuda
If nvcc --version shows 12.x on a container built for CUDA 11, the runtime injection is working. If your application then throws CUDA error: forward compatibility was attempted at runtime, you have a compiled binary that needs a rebuild.
The NVIDIA L4T base images for JetPack 6 are at nvcr.io/nvidia/l4t-base:r36.x.x. Use these as your base image for JP6 container builds.
Xavier on JetPack 6: your options
JetPack 6 does not support Xavier-series modules (AGX Xavier, Xavier NX). JetPack 5.1.x is the last supported release for Xavier hardware.
If you are on Xavier and need to benefit from JP6 improvements, your options:
Option 1 — Stay on JetPack 5.1.x. NVIDIA has not announced an end-of-security-updates date for JP5. For production systems where hardware swap is not viable, staying on JP5 is a legitimate choice through at least 2026.
Option 2 — Upgrade hardware to Orin. Orin modules are pin-compatible with Xavier modules for AGX Orin (same 699-pin connector) and for some Xavier NX → Orin NX carrier boards. Software migration is still required (CUDA, TRT, camera drivers), but you avoid a hardware redesign. Verify pin-compatibility with your specific carrier board before ordering.
Option 3 — Parallel deployment. Keep existing Xavier systems on JP5, migrate new production units to Orin + JP6. Many teams run mixed fleets during transition.
The performance case for moving to Orin is significant — Orin AGX delivers roughly 2.5x the AI TOPS of AGX Xavier (275 vs 32 TOPS sparse INT8) — but the migration cost is real and should be scoped before committing.
What to audit before you start the migration
| Area | What to check | Risk if skipped |
|---|---|---|
| Camera drivers | Do you have custom .c driver files? | 2–5 days of porting work discovered mid-migration |
| TRT engines | List all .engine files in production | Runtime crashes at model load |
| Kernel modules | lsmod and /lib/modules/ on your JP5 system | Modules silently missing on JP6 |
| Python environments | All virtualenvs, conda envs | Import failures in production |
| Hardcoded CUDA paths | Grep for /usr/local/cuda-11 | Runtime errors in scripts |
| Carrier board DTS | Is your DTS derived from JP5 reference? | Boot failures after flash |
If your JP5 system has custom camera drivers or a complex custom carrier board DTS and you need a scoped porting engagement, the Jetson BSP and camera bring-up service covers what that typically involves and how we scope the work.
For the complete camera bring-up process on JetPack 6, see GMSL2 camera bring-up on Jetson Orin. For the JetPack version compatibility table with all L4T releases, see JetPack versions and L4T compatibility.
Relevant Services
NVIDIA Jetson Expert Support
Stuck on a Jetson bring-up?
We've debugged this failure mode before. BSP, device tree, camera pipelines, OTA, most blockers clear in the first session. No long retainers. No guessing.
Frequently Asked Questions
Can I upgrade from JetPack 5 to JetPack 6 via OTA?
No. JetPack 5 and JetPack 6 run on different base OS versions (Ubuntu 20.04 vs 22.04) and incompatible L4T versions (R35 vs R36). OTA from JP5 to JP6 is not supported. You need to reflash.
Will my JetPack 5 camera drivers work on JetPack 6?
Unlikely without porting. The V4L2 subdev API changed between L4T R35 and R36, and the sensor driver framework (tegracam) had breaking changes. Custom camera drivers need to be ported and recompiled against L4T R36 sources.
Why does libcudnn.so.8 not found appear after upgrading to JetPack 6?
JetPack 5 ships cuDNN 8.x. JetPack 6 ships cuDNN 9.x. The shared library filename changed from libcudnn.so.8 to libcudnn.so.9. Any binary compiled against cuDNN 8 needs to be recompiled or the application needs the cuDNN 8 library installed separately.
Does JetPack 6 support the same TensorRT models as JetPack 5?
TensorRT engines are not portable between versions. JP5 used TensorRT 8.x; JP6 uses TensorRT 10.x. You need to re-export your ONNX models and rebuild your TRT engines on the new version. Some deprecated TRT 8 APIs were removed in TRT 10.
What Python version does JetPack 6 use?
JetPack 6 defaults to Python 3.10 on Ubuntu 22.04. JetPack 5 used Python 3.8. This matters if you have PyPI package dependencies that don't have Python 3.10 wheels, or virtualenvs that were built against 3.8.
Which Jetson modules support JetPack 6?
JetPack 6 supports only the Orin family: Jetson AGX Orin, Orin NX, and Orin Nano. It does not support Xavier-series modules (AGX Xavier, Xavier NX, TX2, Nano). If you are on Xavier, JetPack 5.1.x is the last supported release. There is no upgrade path from Xavier to Orin without a hardware change.
How long does a JetPack 5 to 6 migration take for a production Jetson system?
For a system with no custom camera drivers or kernel modules: 1–3 days (reflash, rebuild Python environments, regenerate TRT engines). For a system with custom camera drivers: add 2–5 days of driver porting. For a system with a custom carrier board DTS: add 1–2 days of DTS audit and validation. The total estimate is 3–10 days depending on how much custom BSP work accumulated on the JP5 system.
Is my JetPack 5 GStreamer pipeline compatible with JetPack 6?
Most GStreamer pipelines work without changes. GStreamer 1.22 (JP6) is largely backwards-compatible with 1.16 (JP5) for the core elements and NVIDIA hardware elements. Known incompatibilities: pipelines that use deprecated property names removed in 1.22, and any pipeline relying on pad negotiation behavior that changed between versions. Test your critical pipelines on JP6 before committing to the migration.
Can I run JetPack 5 Docker containers on a JetPack 6 host?
Containers that only use userspace libraries (including CUDA via libcuda) generally work because the container runtime maps in the host's CUDA libraries. Containers that bundle CUDA 11.4 may conflict with the host's CUDA 12.6, use the --env NVIDIA_DRIVER_CAPABILITIES=all flag and verify the library versions being loaded. Containers that require specific kernel modules (V4L2 camera drivers, custom .ko files) will always use the host kernel modules, not container ones.
How do I install PyTorch for JetPack 6?
Use the dusty-nv/jetson-containers project or NVIDIA's Jetson PyPI index (pip.jetson-ai.com). These provide pre-built wheels compiled against CUDA 12.6 and cuDNN 9.x. Do not use pip install torch from PyPI, those are x86 builds and will fail or install silently broken wheels. The correct install is: pip install torch torchvision --index-url https://pypi.ngc.nvidia.com with the JP6-compatible version pinned.
What is the rollback plan if JetPack 6 migration fails?
Flash back to JetPack 5. This requires having your JP5 disk image saved before you start. Use NVIDIA SDK Manager to flash the JP5 image, or use the command-line flash.sh. If you have a custom carrier board DTS, you need the JP5-era DTS saved separately since it will not apply cleanly to JP6. The only way to avoid a painful rollback is to keep the JP5 system physically intact (or imaged) while you bring up a separate JP6 test unit.
Do I need to update my carrier board DTS when migrating from JetPack 5 to JetPack 6?
Almost certainly yes if you have a custom carrier board. L4T R36 (JetPack 6) updated the reference DTS files and changed several node structures. Known breaking changes: DWC3 USB now requires an explicit ref clock entry, PCIe clock references changed on some Orin variants, and ODMDATA format changed for certain board profiles. Start with a diff of your JP5 DTS against the R36 reference DTS for the same Orin module, then apply the structural changes to your custom additions.
Can I test JetPack 6 before committing to a full migration?
Yes, and you should. The safest approach is to bring up a separate Jetson unit on JP6 in parallel with your production JP5 unit. Flash JP6 on the test unit, rebuild your software stack, run your test suite, and validate camera drivers before touching the production system. If you only have one unit, image the JP5 eMMC/SD card first using dd or NVIDIA SDK Manager before reflashing. Never start a migration without a verified restore path.
Written by
Aarón AnguloCo-Founder & CEO · ProventusNova
Obsessed with client outcomes. Aarón ensures every engagement delivers real results, on time, on scope, no exceptions.
Connect on LinkedInRelated Articles
How to use flash.sh on Jetson Orin: parameters, board configs, and common errors
Using flash.sh on Jetson Orin: board configs, recovery mode, partial flash with -k, custom carrier board workflow, and the 5 most common flash errors fixed.
DWC3 error -71 on Jetson: the JetPack 6 clock reference fix
dwc3 error -71 on Jetson Orin under JetPack 6 means a missing ref clock in the device tree. Here's the exact dmesg pattern, why it regressed in L4T R36.
JetPack versions and L4T compatibility: complete reference table
Complete JetPack version to L4T, CUDA, TensorRT, and supported module reference table. Includes how to check your running version and key differences.
Jetson A/B OTA updates: what breaks on custom carrier boards
Jetson Orin A/B slot OTA updates fail differently on custom carrier boards than on devkits. Slot switching not persisting, rollback protection blocks, and.