The LVFS needs additional information about the firmware which is included in the uploaded cabinet archive.

MetaInfo Files

The .metainfo.xml file describes the device and firmware and is extra metadata added to the firmware archive by the OEM or ODM. The file is XML format, and uses a subset of the AppStream component specification.

An example metainfo.xml file looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright 2018 Richard Hughes <> -->
<component type="firmware">
  <name_variant_suffix>Black Friday Special Edition</name_variant_suffix>
  <summary>Firmware for the Hughski ColorHug Ambient Light Sensor</summary>
      Updating the firmware on your ColorHugALS device improves performance and
      adds new features.
    <firmware type="flashed">84f40464-9272-4ef7-9399-cd95f12da696</firmware>
  <url type="homepage"></url>
    <release urgency="high" version="3.0.2" date="2017-02-09" install_duration="120">
      <checksum filename="my-custom-name.bin" target="content"/>
        <p>This stable release fixes the following bugs:</p>
          <li>Fix the return code from GetHardwareVersion</li>
          <li>Scale the output of TakeReadingRaw by the datasheet values</li>
        <issue type="cve">CVE-2016-12345</issue>
        <issue type="cve">CVE-2017-54321</issue>
        <issue type="dell">DSA-2020-321</issue>
        <issue type="intel">INTEL-SA-54321</issue>
        <issue type="intel">INTEL-TA-12345</issue>
        <issue type="lenovo">LEN-28775</issue>
        <issue type="vince">257161</issue>
  <!-- we can optionally restrict this update to specific fwupd versions,
  or even previous firmware or bootloader versions -->
    <id compare="ge" version="0.8.0">org.freedesktop.fwupd</id>
    <firmware compare="ge" version="0.1.2"/>
    <firmware compare="ge" version="0.3.4">bootloader</firmware>
    <value key="LVFS::VersionFormat">example</value>
    <value key="LVFS::UpdateProtocol">org.acme.example</value>
  <!-- these keywords are optional and are used for searching -->

Using GUIDs

GUID means ‘Globally Unique Identifier’ and is a 128-bit integer number used to identify a device. GUIDs are often formatted as strings such as 84f40464-9272-4ef7-9399-cd95f12da696. Another name for GUID is UUID (‘Universally Unique Identifier’) and the two terms can be used interchangeably. When using GUIDs on the LVFS they should always be lowercase.

In fwupd the GUID is generated from the DeviceInstanceId strings, so for a single USB device the GUIDs would be generated like this:

$ python
>>> import uuid
>>> print uuid.uuid5(uuid.NAMESPACE_DNS, 'USB\VID_0A5C&PID_6412&REV_0001')
>>> print uuid.uuid5(uuid.NAMESPACE_DNS, 'USB\VID_0A5C&PID_6412')
>>> print uuid.uuid5(uuid.NAMESPACE_DNS, 'USB\VID_0A5C')

You also can use the online generator to manually convert Instance IDs to GUIDs.

Having multiple GUIDs for each device allows the vendor to choose the GUID for what should match; to match on the vendor+product+revision you’d choose the first one, and the vendor+device you would use the second. We only really use the third GUID for fixing a vendor name, or other very broad quirks that apply to all USB devices from a specific vendor.

In the case for PCI devices and other technologies like NVMe, you can dump the GUIDs generated by fwupd using this tool:

sudo /usr/libexec/fwupd/fwupdtool --plugin-whitelist nvme get-devices --verbose
using e22c4520-43dc-5bb3-8245-5787fead9b63 for NVME\VEN_1179&DEV_010F&REV_01
using 83991323-9951-5adf-b743-d93e882a41e1 for NVME\VEN_1179&DEV_010F
using ad9fe8f7-cdc4-52c9-9fea-31b6f4988ffa for NVME\VEN_1179

More details about the GUID generation scheme used in each plugin can be found in the file in each plugin directory.


Metainfo files can contain as many lines of <firmware type="flashed"> as required and any device with any of the GUIDs will match the firmware file.

AppStream ID

The AppStream <id> has to be unique for each device firmware stream as it used to combine separate <release> tags in the .metainfo.xml files into the metadata catalog that is downloaded by end users.

Choosing the correct AppStream ID is thus very important for correct operation of the front end tools.

Firstly, the AppStream ID should have a lowercase prefix that matches the reverse-DNS name of your vendor, similar to Java. For instance, appropriate prefixes would be com.lenovo… or org.hughski….

The ID should also contain the model type, and perhaps also the module that is being updated if there are (or will be) multiple updates for the same hardware. For instance, we would build the ID further into org.hughski.ColorHug2.BIOS….

The ID should always have a suffix of .firmware, which means the finished AppStream ID for this hardware would be org.hughski.ColorHug2.BIOS.firmware


The ID has to be totally specific to the GUIDs used to match the device. For hardware that uses a different firmware stream it is important that the AppStream ID does not match existing firmware with the same ID. The LVFS will warn you if you try to upload firmware with the same ID and different sets of GUIDs.

Including the mode name is just convention; you can use the partial GUID appended if this helps, e.g. com.hughski.ColorHug84f40464.firmware


Never include forward or backwards slashes in the ID.

Update Category

By telling the LVFS the firmware category to use for the component the front end can correctly translate the update type in the UI. Also for this reason, .metainfo.xml files should not include the words ME, EC, BIOS, Firmware, Device or Update in the component name and they will be removed if included.

The component category can be set as part of the metainfo.xml file or set from the LVFS web console. Most users will want to include the extra metadata to make the upload process quicker for QA engineers. To do this, add this to the metainfo file:


Allowed Category Values


Displayed Name


System Update


Device Update


Embedded Controller Update


Management Engine Update


Controller Update


Corporate ME Update


Consumer ME Update


Thunderbolt Controller


Platform Security Processor


CPU Microcode Update


Configuration Update


Battery Update


Camera Update


TPM Update


Touchpad Update


Mouse Update


Keyboard Update


Storage Controller Update


Network Interface Update


Video Display Update


BMC Update


USB Receiver Update


Drive Update


Flash Drive Update


SSD Update


GPU Update


Dock Update


USB Dock Update


Fingerprint Reader Update


Graphics Tablet Update

Update Protocol

The LVFS needs to know what protocol is being used to flash the device. The protocol value is used to provide information about the security of the firmware update to end users.

The update protocol can be set as part of the metainfo.xml file or set from the LVFS web console. Most users will want to include the extra metadata to make the upload process quicker for engineers. To do this, add this to the metainfo file:

  <value key="LVFS::UpdateProtocol">some-value-here</value>

The latest allowed values for LVFS::UpdateProtocol can be found using the LVFS.

Device Integrity

Some update protocols just transport the image to the target device and make no guarantee of the signing requirements. Such “generic” protocols include NVMe, ATA, DFU and many others.

The device integrity mechanism can be set as part of the metainfo.xml file or set from the LVFS web console.

To do this, add this to the metainfo file:

  <value key="LVFS::DeviceIntegrity">some-value-here</value>

The allowed values for LVFS::DeviceIntegrity are:

  • signed : The firmware payload is verified on-device the payload using strong cryptography such as RSA, AES or ECC. It is usually not possible to modify or flash custom firmware not provided by the vendor.

  • unsigned: The firmware payload is unsigned and it is possible to modify and flash custom firmware.

Version Format

Some hardware returns the version number as a string such as 1.23.4567, and this is easily handled as a semantic version. In other cases we are not so lucky, and the hardware returns a uint16_t or uint32_t with no extra metadata about how it should be formatted. This lack of specification precision means that different vendors have chosen to convert the large integer number to various different forms.

The latest allowed values for LVFS::VersionFormat can be found on the LVFS.

To override the default of unknown vendors should ship extra metadata in the metainfo.xml file:

  <id compare="ge" version="1.2.0">org.freedesktop.fwupd</id>
  <value key="LVFS::VersionFormat">intel-me</value>

If the version format is unspecified, and cannot be derived from the LVFS::UpdateProtocol then a warning will be shown during upload and the firmware cannot be moved to stable until this is resolved.

Various security teams also want us to always show the device firmware version with the correct format, even if an update is not available. This may be for audit reasons, or just so customers know the version of the firmware compared to release notes written for another operating system. For instance, if the vendor release notes says the firmware should be any version above 39.0.45.x (formatted as a quad) and the user is running 39.0.11522 (formatted as a triplet) it is not clear to the user what to do.

To change from the default triplet version format we can set a fwupd quirk on the hardware device. For instance, changing the UEFI Lenovo ME device to use the intel-me format. Quirk files can be added upstream for future fwupd versions, or simply copied to /usr/share/fwupd/quirks.d. The fwupd daemon will detect the new file and refresh devices as required.

Device Flags

Some device flags can be populated from the firmware metadata, rather than the more traditional way of setting in a per-plugin .quirk file or in the plugin code itself. This allows device flags to be pushed from the server to the client.

For instance, on some hardware, the UEFI UpdateCapsule process would fail to deploy because there was no HDMI/DP display attached. Firmware can opt-in to this new requirement by setting a device flag that gets copied to the local fwupd device. If the client is new enough, then any firmware that opts-in then the user will be warned before the update is scheduled that a display must be connected to continue – which is a much better user experience than it failing after the user has rebooted to deploy the update.

To use this, the internal device flag can be populated from the firmware metadata:

  <value key="LVFS::DeviceFlags">display-required</value>

The exact flags that are allowed for each protocol are restricted, and the allowed values for LVFS::DeviceFlags (along with fwupd requirements) can be found via the LVFS.


Only fwupd versions greater or equal to 1.9.1 are able to copy device flags from the metadata, and only devices with the FU_DEVICE_INTERNAL_FLAG_MD_SET_FLAGS flag set. If you require the device flag to be set for a successful update then you should also have the correct fwupd version requirement to ensure the flag get copied. e.g.

  <id compare="ge" version="1.9.6">org.freedesktop.fwupd</id>

Please contact the LVFS administrator if other flags from FuDevice or FwupdDevice are required to be set by the metadata.

Adding Restrictions

When the user requests updates for a specific device, all the GUIDs provided by the device will be match against any of the GUIDs in the metadata. To limit these matches using a variety or requirements the <requires> tag can be used. For instance, the update can be conditional on the firmware version of another device, or on the kernel version of the installed system.

Requirements can use different methods to compare version numbers.









Not equal



Less than



Less than or equal



Greater than



Greater than or equal



Filename glob



Perl compatible regular expression

Using CHID

Newer versions of fwupd can restrict updates to a specific Computer Hardware ID, much like Microsoft update:

  <id compare="ge" version="1.0.8">org.freedesktop.fwupd</id>

If multiple <hardware> entries are specified (using an OR | separator) then any may be present.

  <id compare="ge" version="1.0.8">org.freedesktop.fwupd</id>

Using fwupd >= 1.9.10 the uploader can also deny updates to a specific Computer Hardware IDs:

<!-- only newer versions of fwupd understand 'not_hardware' requirements -->
  <id compare="ge" version="1.9.10">org.freedesktop.fwupd</id>

CHIDs can also be added or removed in the LVFS web UI, but only before the firmware is published to stable channel.

component requirements

Modifying requirements of an uploaded firmware.

Other Firmware Version

Newer versions of fwupd can restrict updates on one device depending on the version of firmware on another device. This is most useful when requiring a minimum EC controller version before updating a system firmware, or when a modem firmware needs a specific fix for the baseband firmware:

  <id compare="ge" version="1.1.3">org.freedesktop.fwupd</id>
  <firmware compare="ge" version="0.1.2">6de5d951-d755-576b-bd09-c5cf66b27234</firmware>

Newer versions of fwupd can restrict updates on one device depending if another firmware GUID exists on the system of any version. This is similar to the CHID method above but uses the GUID of the firmware, not a hardware ID.

This can be used to ensure that a specific embedded controller is detected for a specific system firmware update, for example.

  <id compare="ge" version="1.2.11">org.freedesktop.fwupd</id>

Parent Version

For composite devices such as docks you might want to restrict the child device with respect to the parent, for instance requiring the parent to have greater than a specific bootloader version number.

The other useful thing to use this for is checking if the parent has a specific GUID (of any version) which allows us to match against the common VID&PID instance IDs. This would allow us to restrict a generic child device update to a specific OEM vendor parent.

Depth is specified as 1 to match the parent device and 2 to match the grandparent device:

  <id compare="ge" version="1.3.4">org.freedesktop.fwupd</id>
  <firmware depth="1" compare="ge" version="0.1.2">bootloader</firmware>
  <firmware depth="1">12345678-1234-1234-1234-123456789012</firmware>

Newer versions of fwupd can understand an OR requirement using a | separator between the listed GUIDs.

<!-- only newer versions of fwupd understand parent OR requirements -->
  <id compare="ge" version="1.8.9">org.freedesktop.fwupd</id>
  <firmware depth="1">12345678-1234-1234-1234-123456789012|6de5d951-d755-576b-bd09-c5cf66b27234</firmware>

Sibling Version

Composite devices can also specify that a device sibling has to exist, optionally with a specific version. To do this, specify the depth as 0:

<!-- only newer versions of fwupd understand the 'depth' property -->
  <id compare="ge" version="1.6.1">org.freedesktop.fwupd</id>
  <firmware depth="0">12345678-1234-1234-1234-123456789012</firmware>

Child Version

Composite devices can also restrict the parent device with respect to the child. This is useful when a generic parent device has vendor-specific child devices attached. To do this, specify the depth as -1 to match any child device.

<!-- only newer versions of fwupd understand the negative 'depth' property -->
  <id compare="ge" version="1.9.7">org.freedesktop.fwupd</id>
  <firmware depth="-1">12345678-1234-1234-1234-123456789012</firmware>

Client Features

Versions of fwupd >=1.4.5 can restrict updates depending on the features the client can provide. For instance, if the tools are being run in non-interactive mode then it may not be possible to ask the user to perform a manual action.

Some devices may need to show the user some text or an image of how to manually detach the firmware from runtime mode to bootloader mode.

  <screenshot type="default">
    <caption>Unplug the controller, hold down L+R+START for 3 seconds until both LEDs are flashing then reconnect the controller.</caption>
  <id compare="ge" version="1.4.5">org.freedesktop.fwupd</id>

Other firmware may require showing the user a message or image on how to reset the hardware when the firmware update has completed. This specific post-update message functionality is only available for specific protocols and implemented in some versions of fwupd and GNOME Software.

Post-installation dialog

Showing the user some instructions to reboot the hardware.

This action can be performed with one or two metadata keys set in the .metainfo.xml file, or chosen using the LVFS component editor.

  <value key="LVFS::UpdateMessage">Please turn the device off and back on again for the update to complete</value>
  <value key="LVFS::UpdateImage"></value>
</custom><!-- only newer versions of fwupd understand 'client' requirements -->
  <id compare="ge" version="1.4.5">org.freedesktop.fwupd</id>


You can include either the UpdateImage or <image> PNG file in the cabinet archive rather than uploading it. In this case use a URL with a file:// prefix, e.g. file://unifying-power.png.

The image will still be mirrored onto the LVFS CDN at upload time, as there is no ability for GUI clients to read binary files from inside the cabinet archive. This means that internet access will still be required when deploying firmware if the image is specified.

Restricting Direct Downloads

If you’d rather not have users downloading the .cab archive directly you can opt to hide the direct download links in the LVFS search results. To do this, add this to the metainfo file:

<!-- most OEMs do not need to do this... -->
  <value key="LVFS::InhibitDownload"/>

Embargoed and Sanctioned Countries

The LVFS administrator can configure the policy for all firmware owned by the vendor to be blocked from download in embargoed or otherwise sanctioned countries.

The blocked ISO 3166 country codes can also be specified in the firmware itself, using the LVFS::BannedCountryCodes metadata key.

  <value key="LVFS::BannedCountryCodes">SYR</value>

Source Requirements

If a vendor is distributing firmware which contains GPL licensed parts (for example the Linux kernel) then they must include a source URL for the GPL licensed parts in the releases section in the metainfo file. This should point to the release-specific source code that can be used to rebuild the binary from the code, for instance:

  <release urgency="low" version="1.2.6" >
  <url type="source"></url>

GPL firmware without source information can not be moved to testing or stable. You can also edit or add the source URL in the existing Update Details section in the component view:

component source URL

Component Tags

Tags can be used to identify a vendor-specific keyword to the component release, for example identifying components included in a specific service pack or combined update.

Users with fwupd version >= 1.7.3 can install multiple firmware files using the tag value. For example setting HostBkc=vendor-factory-2021q1 in /etc/fwupd/daemon.conf` and then doing ``fwupdmgr sync-bkc will install all firmwares with that matching tag.

  <value key="LVFS::UpdateProtocol">some-value-here</value>
  <tag namespace="lvfs">vendor-factory-2021q1</tag>

Tag element values should be lowercase, have no whitespace and be namespaced with the vendor name to avoid conflicts.

Vendors wanting to use component tags should ask the LVFS administrator to enable access.

Device Icons

The icon show in GUI fwupd clients is normally set by the plugin automatically. In some cases the plugin may not know the appropriate icon until firmware has been uploaded to the LVFS.

For this cosmetic purpose the firmware uploader can specify the stock icon in the metainfo.xml file which gets put in the the AppStream metadata and used by the graphical clients. In most cases specifying the icon is not required.

To manually override the icon to one of the stock values, use this:

    <icon type="stock">battery</icon>

Valid stock icons include:







































































































Composite Hardware

A vendor can build a single .cab archive with multiple firmware files with different .metainfo.xml files describing them. This allows a single file to be used to update either multiple devices, or a single composite device. An example of a composite device would be a Dell dock, where electrically there are various components connected using USB, but physically it looks like one piece of hardware. Wacom does the same for the various Intuit tablets.

Some tools such as gnome-software may be unable to show more than one update description for the single .cab file. The LVFS also needs to know how to sort the components inside the firmware when showing the logged in user.

To solve this, assign the firmware components a priority, where higher numbers are better. For example main.metainfo.xml:

<?xml version="1.0" encoding="utf-8"?>
<component priority="1" type="firmware">
  <name>Hughski Dock Update</name>

and also rts1234.metainfo.xml:

<?xml version="1.0" encoding="utf-8"?>
<component type="firmware">
  <name>RTS1234 Update for Hughski Dock</name>

and atmel567.metainfo.xml:

<?xml version="1.0" encoding="utf-8"?>
<component type="firmware">
  <name>ATMEL567 Update for Hughski Dock</name>
topology cli output

Showing the topology of a dock device.

The priority can also influence the composite install order. Client-side, fwupd will check the explicit device order (e.g. Flags=install-parent-first) and then fallback to the component priority where higher numbers are installed first. This can be used to ensure that releases are always installed in a specific order.

If the priority is specified on the component it is used for all releases, but if per-release control of the composite device is needed, it can instead be set on the release node, e.g.

  <release priority="5">
  <!-- only newer versions of fwupd understand per-release priorities -->
  <id compare="ge" version="1.9.10">org.freedesktop.fwupd</id>

In the case where the update order is different between releases the component or device should probably also have Flags=install-all-releases to ensure that every version is installed with a predictable release order.

Further Details

There are currently quite strict limits on the format of the release description included in the description part of the metainfo, or edited on the LVFS. For instance, OEMs are not allowed to include links within the text and have to adhere to a limiting style guide. As a workaround, all firmware can now specify an additional url:

  <url type="details"></url>

This should point to a website page or PDF description of the specific release. This would allow vendors to provide more information about specific CVEs or provide more technical information mentioned in the update details. Whist the update details should still be considered the “primary” method to convey information about the firmware release, the URL may be useful for larger OEMs with existing contractual requirements.

Release Urgency Values

It is important to set the urgency of the release to the correct value as this may influence how the client notifies the user. For instance, critical updates may cause a daily session notification to the user, but low priority updates might only be visible when the user manually visits the software center.




Low importance


Medium importance, e.g. optional update


High importance, e.g. recommended update


Critical importance, e.g. urgent or security issue


In some circumstances we may need to ask the user to perform an action to manually put the device into a special firmware-update mode. We can achieve this using a translatable update caption and an optional line-art image:

Pre-installation dialog

Showing the user some instructions before updating firmware.

To achieve this the firmware needs to declare the public location of the image in the metainfo file:

<?xml version='1.0' encoding='UTF-8'?>
  <component type="firmware">
      <screenshot type="default">
        <caption>Unplug the controller, hold down L+R+START for 3 seconds until both LEDs are flashing then reconnect the controller.</caption>

In the public metadata the URL is rewritten to use the LVFS CDN to preserve the privacy of the remote client.

The screenshot will only be shown by the front end client when the device has the _NEEDS_BOOTLOADER flag.

Please also add a <client> requirement if the update cannot be performed without showing the image or caption.

Generic Components

Vendors can include an extra .metainfo.xml file with the <component type="generic"> to supply information used by the LVFS to identify the top-level device. This is only useful when there is no obvious existing high-priority component that can be used for display.

This would be useful for a dock to have the title WonderDock2 rather than showing a seemingly random sub-component of it on the public pages.

An example generic.metainfo.xml file would look like this:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright 2020 Richard Hughes <> -->
<component priority="9" type="generic">
  <summary>Firmware for the ACME WonderDock</summary>
  <url type="homepage"></url>

A generic component can also be created for composite firmware manually on the LVFS for firmware that has already been uploaded.

Style Guide

When all vendors use the same style everything looks more consistent for the end user. Here are some of our suggestions:


  • Use a short device name, e.g. “ThinkPad P52s” or “ColorHug 2”.

  • Use a UTF-8 character (e.g. ™ or ®) rather than (R) if required

  • Don’t include the vendor name


If a component matches two components with the same GUID, please use a forward slash to delimit each model and specifier, for instance, you SHOULD do this:

  • <name>ThinkPad T580/ThinkPad P52s</name>

…and NOT do any of these:

  • <name>ThinkPad T580/P52s</name>

  • <name>FC30,NES30</name>

  • <name>ColorHug2 &amp; ColorHug2.1</name>.

To avoid specifying multiple components in the <name> you could also have one firmware payload in the cabinet archive referenced by two different .metainfo.xml files – each with a different DMI CHID, parent or child requirement.


  • Only use this optional tag if the <name> would be duplicated, e.g. if there are two variants of the same hardware

  • Use a short string, as it will be appended to the visible name with brackets if required

  • Don’t duplicate any part of the name


  • Only use this optional tag if there are multiple vendors providing different firmware streams for the same hardware.

  • Use a familiar lower case single word string, as it will be shown in the UI


  • Refer to the type of hardware, e.g. “Firmware for the Hughski ColorHug Colorimeter”

  • Include the vendor name before the full device description

  • Use a UTF-8 character (e.g. ™ or ®) rather than (R) if required


  • Try to avoid explaining the implementation details of the fix, e.g. “Ensure accurate color profile creation with high screen brightness.” rather than “Fix overflow in counter when over 500 Lux detected.”

  • Do not use overly technical descriptions when simpler text would suffice, e.g. use “Fix LED color during system start up.” rather than “Fix LED color during POST.”

  • Try to describe fixed bugs and new features from the point of view of the user and how it affects them

  • For security or important updates also include the effect of not applying the update, e.g. “Disk corruption resulting in possible data loss may occur until this update is installed.”

<release tag="N1NET43W" …>

  • The release tag may be optional or required based on component category and vendor policy. If provided it can used to show a vendor-specific text identifier that is different from the version number.

  • The tag may be unique only to the model, or be unique for the entire vendor.

  • This attribute should not be used if the tag is not used to identify the specific firmware on the vendor homepage.

  • Depending on vendor policy, the release tag may be displayed with the header External release Software ID or Machine Type Model.