diff --git a/lib/bb/parse/ast.py b/lib/bb/parse/ast.py
index a372b3534e4..a828c49c937 100644
--- a/lib/bb/parse/ast.py
+++ b/lib/bb/parse/ast.py
@@ -367,12 +367,13 @@ class AddFragmentsNode(AstNode):
         def check_and_set_builtin_fragment(fragment, data, builtin_fragments):
             prefix, value = fragment.split('/', 1)
             if prefix in builtin_fragments.keys():
-                if data.getVar(builtin_fragments[prefix], noweakdefault=True) != None:
+                fragment_var, fragment_type = builtin_fragments[prefix][0], builtin_fragments[prefix][1]
+                if fragment_type == "set" and data.getVar(fragment_var, noweakdefault=True) is not None:
                     bb.fatal(
                         ("A builtin fragment '%s' is used while %s has already got an assignment.\n"
                          "Please either disable the fragment or remove the value assignment.\n"
                          "To disable the fragment, use 'bitbake-config-build disable-fragment %s'."
-                         ) % (fragment, builtin_fragments[prefix], fragment))
+                         ) % (fragment, fragment_var, fragment))
                 fragment_history = data.varhistory.variable(self.fragments_variable)
                 loginfo={}
                 for fh in fragment_history[::-1]:
@@ -381,15 +382,27 @@ class AddFragmentsNode(AstNode):
                         loginfo["line"]   = fh["line"]
                         loginfo["detail"] = f"{value} ({self.fragments_variable} contains \"{fragment}\")"
                         break
-                # parsing=True since we want to emulate X=Y and allow X:override=Z to continue to exist
-                data.setVar(builtin_fragments[prefix], value, parsing=True, **loginfo)
+                if fragment_type == "set":
+                    # parsing=True since we want to emulate X=Y and allow X:override=Z to continue to exist
+                    data.setVar(fragment_var, value, parsing=True, **loginfo)
+                elif fragment_type == "add":
+                    data.appendVar(fragment_var, f" {value.strip()}", **loginfo)
+                else:
+                    bb.fatal(f"Unknown fragment type '{fragment_type}' "
+                             f"(from '{prefix}:{fragment_var}:{fragment_type}' in {self.builtin_fragments_variable})")
                 return True
             return False
 
         fragments = data.getVar(self.fragments_variable)
         layers = data.getVar('BBLAYERS')
         flagged_variables = data.getVar(self.flagged_variables_list_variable).split()
-        builtin_fragments = {f[0]:f[1] for f in [f.split(':') for f in data.getVar(self.builtin_fragments_variable).split()] }
+        builtin_fragments = {}
+        for fragment in data.getVar(self.builtin_fragments_variable).split():
+            fragment = fragment.split(':')
+            builtin_fragments[fragment[0]] = (
+                fragment[1],
+                "set" if len(fragment) < 3 else fragment[2],
+            )
 
         if not fragments:
             return
@@ -402,7 +415,7 @@ class AddFragmentsNode(AstNode):
                     fragments.split(),
                 )
             )
-            if len(builtin_fragments_list) > 1:
+            if len(builtin_fragments_list) > 1 and not builtin_fragments[builtin_fragment_key][1] == "add":
                 bb.warn(
                     ("Multiple builtin fragments are enabled for %s via variable %s: %s. "
                      "This likely points to a mis-configuration in the metadata, as only "
