diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py
index b848623a6e7..6156ad9840b 100644
--- a/meta/lib/oeqa/selftest/cases/devtool.py
+++ b/meta/lib/oeqa/selftest/cases/devtool.py
@@ -2339,7 +2339,7 @@ class DevtoolUpgradeTests(DevtoolBase):
         except:
             self.skip("Git user.name and user.email must be set")
 
-    def _check_changelog(self, recipe, oldrecipefile, old_ver=None, new_ver=None):
+    def _check_changelog(self, recipe, oldrecipefile, old_ver=None, new_ver=None, changelog_skip=False):
         """Compare extracted changelog against reference data."""
         changelog_ref = oldrecipefile + '.changelog'
         self.assertExists(changelog_ref, 'Changelog reference file must exist for %s' % recipe)
@@ -2366,6 +2366,7 @@ class DevtoolUpgradeTests(DevtoolBase):
             if new_ver:
                 self.assertEqual(metadata.get('new_version'), new_ver)
             self.assertEqual(metadata.get('changelog_file'), '%s.txt' % recipe)
+            self.assertEqual(metadata.get('changelog_skip'), changelog_skip)
 
     def test_devtool_upgrade(self):
         # Check preconditions
@@ -2383,6 +2384,8 @@ class DevtoolUpgradeTests(DevtoolBase):
         oldrecipefile = get_bb_var('FILE', recipe)
         tempdir = tempfile.mkdtemp(prefix='devtoolqa')
         self.track_for_cleanup(tempdir)
+        # Flag the changelog as badly formed; checked in the JSON metadata below
+        self.append_config('RECIPE_UPGRADE_CHANGELOG_SKIP = "%s"' % recipe)
         # Check that recipe is not already under devtool control
         result = runCmd('devtool status')
         self.assertNotIn(recipe, result.output)
@@ -2407,7 +2410,7 @@ class DevtoolUpgradeTests(DevtoolBase):
             newlines = f.readlines()
         self.assertEqual(desiredlines, newlines)
         # Check changelog
-        self._check_changelog(recipe, oldrecipefile, old_version, version)
+        self._check_changelog(recipe, oldrecipefile, old_version, version, changelog_skip=True)
         # Check devtool reset recipe
         result = runCmd('devtool reset %s -n' % recipe)
         result = runCmd('devtool status')
diff --git a/scripts/lib/devtool/upgrade.py b/scripts/lib/devtool/upgrade.py
index ba7348664fd..6cec34d2d5a 100644
--- a/scripts/lib/devtool/upgrade.py
+++ b/scripts/lib/devtool/upgrade.py
@@ -695,7 +695,8 @@ def _cleanup_changelog(content):
     return _join_single_line_paragraphs(text)
 
 
-def _extract_changelog(srctree, pn, old_ver, new_ver, old_tag, new_tag, workspace_path, is_git_source):
+def _extract_changelog(srctree, pn, old_ver, new_ver, old_tag, new_tag, workspace_path, is_git_source,
+                       changelog_skip=False):
     """Extract changelog between old and new version using devtool git tags."""
     changelog_content = None
     changelog_fname = None
@@ -803,6 +804,9 @@ def _extract_changelog(srctree, pn, old_ver, new_ver, old_tag, new_tag, workspac
         'new_version': new_ver,
         'changelog_file': os.path.basename(changelog_path),
         'changelog_source': changelog_fname.split(', ') if changelog_fname else None,
+        # Hint from RECIPE_UPGRADE_CHANGELOG_SKIP: changelog is badly formed
+        # for use in a commit message
+        'changelog_skip': changelog_skip,
     }
     metadata_path = os.path.join(changelog_dir, '%s.json' % pn)
     with open(metadata_path, 'w') as f:
@@ -898,9 +902,11 @@ def upgrade(args, config, basepath, workspace):
         is_git = old_srcrev is not None
         newpv = args.version or rd.getVar('PV')
         new_tag = 'devtool-base-new' if is_git else 'devtool-base-%s' % newpv
+        changelog_skip = rd.getVar('BPN') in (rd.getVar('RECIPE_UPGRADE_CHANGELOG_SKIP') or '').split()
         changelog_file = _extract_changelog(srctree, pn, old_ver, newpv,
                                             'devtool-base', new_tag,
-                                            config.workspace_path, is_git)
+                                            config.workspace_path, is_git,
+                                            changelog_skip)
         if changelog_file:
             logger.info('Changelog extracted to %s' % changelog_file)
             metadata_file = os.path.join(os.path.dirname(changelog_file), '%s.json' % pn)
