The honest framing: there is no official procedure
We went looking for Unitree’s firmware update instructions for the G1 so we could write them up properly. They do not exist in any form we could retrieve on 2026-08-19, and we want to be specific about how hard we looked, because the absence is the most useful thing on this page.
The official G1 User Manual is currently at V1.6, republished 2026-08-12 — eight days before this article. We read all 31 pages. Its table of contents runs: disclaimer, safety instructions, product overview, how to charge, instructions for use, abnormal condition description, precautions, daily care and maintenance, interface/sensor description, and the regulatory statements. There is no “firmware,” “update,” “OTA,” or “upgrade” section. The one place you’d expect it — “Connecting to the Unitree Explore App” — covers account binding and AP-versus-Wi-Fi mode only. The “Abnormal Condition Description” section lists five failure modes (self-test failure, fall self-protection, app connection abnormality, remote control module failure, and the robot falling); none of them is firmware-related.
Unitree’s developer documentation site, support.unitree.com, returns HTTP 567 with a 7 KB
empty page shell to every request we made, including with a complete browser header set. Its own
JavaScript bundle, robots.txt, and sitemap.xml return 567 as well, so there is no underlying
API to read. We then queried the Internet Archive across the whole domain: 563 distinct archived
URLs, every one an empty shell, and — the important part — no firmware, OTA, or update path
anywhere in two years of archived G1 documentation.
So: no procedure, no changelog, no published preconditions, no documented rollback. If you find a blog that confidently tells you to update “on the charger with at least 50% battery,” check whether it cites anything. We traced that specific claim to a repair-shop SEO page that serves 403 to every real client and has never been archived. We will not repeat a battery threshold, because no verifiable source publishes one.
The version history, with dates
This is assembled from dated primary sources, not from a Unitree changelog, because there isn’t one.
| Version | What’s known | Evidence |
|---|---|---|
| 1.4.0 | “Bionic locomotion” introduced | RoboStore video description, 2025-06-18 |
| 1.4.5 | Adds Training Mode — pose the robot by hand to record motion sequences, no code | RoboStore blog, 2025-11-13 |
| v1.4.9 | Removes FSM state 501 from 1-DoF-waist robots | CMU Robotics Knowledgebase |
| 1.5.1 | New per-device key breaks every third-party client | GitHub issue, 2026-04-11 |
| 1.5.2 | Confirmed in the field; video regression reported | GitHub issues, 2026-05-12 / 05-20 |
1.5.2 is the highest version we could verify anywhere. RoboStore is the official US
distributor, so its Training Mode claim is usable, but treat its blog as marketing rather than
documentation. Note also that docs.quadruped.de labels its pages “Firmware V1.0.2” and “V1.0.4”
— a different numbering scheme entirely. Don’t try to reconcile the two.
What updates have actually broken
This is the part with real evidence behind it, and it’s why “just take every update” is not obviously correct advice on this machine.
An update removed a capability (v1.4.9). The G1’s high-level motion controller exposes finite
state machine IDs: 500 is Regular Mode for the 1-DoF-waist robot, 501 is Regular Mode for the
3-DoF version, and 801 is Running Mode. State 500 exhibits jittering; 501 and 801 don’t, which is
why the CMU Robotics Knowledgebase
recommends replacing LocoClient::Start() calls with SetFsmId(501) or SetFsmId(801). Its
author then records this: “Starting in firmware version v1.4.9, it seems the 1 DoF G1 can no
longer use state 501, constraining it to the broken locomotion policy.” Note the hedge —
“it seems” — this is one named researcher’s careful observation, not a vendor notice. Also worth
knowing: locking the waist via the Explore app makes a 3-DoF G1 behave as the 1-DoF version.
An update locked out every existing tool for three weeks (1.5.1). Firmware 1.5.1 changed the
LAN signaling handshake to return data2=3, meaning the robot’s embedded RSA public key is now
wrapped under a per-device AES-128-GCM key stored on the robot at
/unitree/etc/key/aes_key.bin. Without that key the WebRTC handshake can’t proceed and the
connection never starts. The issue report
from 2026-04-11 is blunt: “G1 Robots running the latest firmware v1.5.1 now return data2=3
from the local /con_notify endpoint (port 9991). I haven’t been able to connect since the update.”
The maintainer’s first reaction was “Will take some time to crack it.” A working fix landed
2026-05-01 — roughly three weeks during which updated robots were unreachable by existing
tooling. The key is per-device and stable across re-pairings, and it has to be fetched from
Unitree’s cloud.
Fixing it needs a library upgrade, not just the key — one operator reported a clean handshake on 1.5.2 only after moving the driver from 2.0.4 to 2.1.2.
And matching versions doesn’t guarantee everything works. A separate report on firmware 1.5.2
with a current library has signaling, key auth, and a connected WebRTC peer — but “Video never
produces any frames,” while Unitree’s own mobile app displays video from the same robot fine.
Concrete error codes worth recognizing after a version change, from operators running G1 EDU
on 1.4.5: 7303 for sport requests carrying arm commands, 3203 (“Go2 only”) for sport
commands over WebRTC, 7403 for a custom gesture via api_id 7112, and a 504 timeout
during FSM transitions if you don’t connect in a stable damping state. Audio capture returned
zero frames on 1.4.5.
A mode appeared that doesn’t work. One G1 EDU operator reported in October 2025 that after a firmware update a “Climb” function showed up in the app, but the robot “just makes a lot of noise and stumbles” and “you can not go to any other mode than damping mode.” That thread has zero replies — one operator, never corroborated or answered by anyone. We’re including it because it matches the pattern, not because it’s confirmed.
Version-matching: pin your SDK, not just your firmware
The firmware is only one of four things that have to agree — firmware, the Explore app, the SDK, and any integrator stack on top.
- The SDK pin is explicit. Unitree’s own
xr_teleoperateREADME requires that for v1.1 and above you check outunitree_sdk2_pythonat commit404fe44or newer. Its--motionflag supports Regular mode (R1+X) only — Running mode (R2+A) is explicitly unsupported. - The app’s own interface moves. A driver release on 2026-08-17 notes the
AppNameheader the G1 sends changed fromG1toB2to match the app. - Integrator stacks drift independently. MYBOTSHOP G1 owners hitting
ModuleNotFoundError: No module named 'g1_webserver.libwebserver'are looking at a stale clone of theqre_g1repo, per MYBOTSHOP staff — a vendor ROS 2 stack out of date, not a Unitree firmware fault. Re-clone and set execute permissions.
Practically: write down your firmware, app, and SDK versions before you touch anything, and if you depend on third-party tooling, check whether it has shipped a release naming your target firmware before you update. That’s the single habit that would have spared everyone in the 1.5.1 window.
What we can tell you about updating safely
No official preconditions exist for the update itself. What the V1.6 manual does establish, and what’s adjacent enough to matter:
- Charge with the pack out and switched off. The manual: “Before charging the battery, ensure that the battery pack is switched off. Otherwise, the battery and charger may be damaged,” and the pack must be removed from the robot to charge. Let it cool to room temperature first. “It is strictly prohibited to use unofficial chargers to charge G1 batteries.”
- Know which LED you’re reading. The four-LED 0–25/25–50/50–75/75–100% table in the manual is the handheld remote’s indicator. The robot battery pack works the opposite way: while charging it flashes at 1 Hz, and “if the battery indicator is off, the battery pack is fully charged.” An unlit pack means full, not flat.
- Have the panic button ready. Per quadruped.de’s controls documentation: if the G1 enters an unexpected state, L2 + B puts it into damping mode and it slowly settles to the ground.
- Don’t recalibrate to “fix” post-update behaviour. The manual is explicit: “G1 has been calibrated by default after leaving the factory. Do not recalibrate the joints for normal use!”
One adjacent note, clearly labeled: on the Go2 — not the G1 — Unitree told an owner that a security-focused update “changed the default status of the OTA service and STA-T remote control service to off,” re-enabled under Device → Service Status and Device → Permission Management. A G1 owner posted the same symptom in that thread in March 2026, but we have no Unitree statement covering the G1.
Rollback: there isn’t one documented
We searched specifically for a G1 downgrade or recovery path and found nothing. The closest
documented precedent is on the Go2, and it’s a warning rather than a procedure: the archived
RoboVerse wiki’s restore-to-stock page notes that on Secure Boot units, updating to 1.1.2 “will
NOT boot normally and will remain in Loader loop mode,” because it flashes a boot partition from
a non-Secure-Boot robot, and adds that if the robot still won’t stand after reflashing the correct
boot.img, “do NOT attempt to flash the preloader or U-Boot, as this will brick the device.”
That wiki is offline; the link above is an Internet Archive snapshot. Again: Go2, not G1 — but
it establishes that Unitree firmware can break a boot chain, and that the G1 has no published
recovery route if it does.
For context on why rollback is hard here, a 100-page security study of the G1
from Alias Robotics found the update path runs through ota_box and ota_update services
supervised by a master service, with persistent MQTT-over-TLS sessions to Unitree’s cloud on
port 17883 (robot-mqtt.unitree.com in China, global-robot-mqtt.unitree.com elsewhere).
Firmware is encrypted with a two-layer scheme the paper calls FMX — an LCG stream cipher over
Blowfish ECB with a 128-bit key. Updates are a cloud-delivered, vendor-controlled channel; there
is no local package you can hold back or re-apply.
The takeaway
Updating a G1 is not a routine maintenance task with a documented procedure — it’s an undocumented, one-way, cloud-delivered change to a machine that costs as much as a car. Treat every update as a change window: record your firmware, app, and SDK versions first; confirm your tooling supports the target version before you take it; expect no rollback; and don’t act on any “safe update checklist” that can’t show you its source. Nothing here is a reason to run ancient firmware forever — 1.5.1’s per-device keying is a genuine security improvement — but it is a reason to update deliberately rather than reflexively.
If you’re troubleshooting a robot that’s already been updated and the app is misbehaving, start with our Unitree app-crash-after-firmware-update guide.