Problem/Motivation

Update manager is crashing admin panel for versions 9x, 10x with following message:

The website encountered an unexpected error. Try again later.

UnexpectedValueException: Invalid version string "main" in Composer\Semver\VersionParser->normalize() (line 191 of /var/www/vendor/composer/semver/src/VersionParser.php).

Composer\Semver\Semver::satisfies('main', '>= 10.2.3') (Line: 56)
Composer\Semver\Semver::Composer\Semver\{closure}('main')
array_filter(Array, Object) (Line: 57)
Composer\Semver\Semver::satisfiedBy(Array, '>= 10.2.3') (Line: 86)
Drupal\update\ProjectCoreCompatibility->getPossibleCoreUpdateVersions(Array) (Line: 65)
Drupal\update\ProjectCoreCompatibility->__construct(Array, Array) (Line: 106)
update_calculate_project_data(Array) (Line: 40)
update_requirements('runtime') (Line: 91)
update_page_top(Array) (Line: 352)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}(Object, 'update') (Line: 388)
Drupal\Core\Extension\ModuleHandler->invokeAllWith('page_top', Object) (Line: 353)
Drupal\Core\Render\MainContent\HtmlRenderer->buildPageTopAndBottom(Array) (Line: 146)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 186)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 76)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 28)
Drupal\Core\StackMiddleware\ContentLength->handle(Object, 1, 1) (Line: 32)
Drupal\big_pipe\StackMiddleware\ContentLength->handle(Object, 1, 1) (Line: 270)
Drupal\shield\ShieldMiddleware->bypass(Object, 1, 1) (Line: 137)
Drupal\shield\ShieldMiddleware->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 36)
Drupal\Core\StackMiddleware\AjaxPageState->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object, 1, 1) (Line: 704)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

Issue fork drupal-3567483

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

cassius created an issue. See original summary.

cassius’s picture

Title: Update manager crashed admin panel » Update manager crashing admin panel
longwave’s picture

Thanks for the report, this relates to the recent opening of the main branch. I think this will have to be fixed server side given code that is out in the wild is already crashing.

jpoesen’s picture

Confirming this on D8.9.20.

Navigating to any admin page yields a white screen of death:

The "main" version string, it seems, throws an UnexpectedValueException in vendor/composer/semver/src/VersionParser::normalize(), called by core/modules/update/src/ProjectCoreCompatibility::getPossibleCoreUpdateVersions().

longwave’s picture

Issue tags: -updatemanager core

Opened #3567494: Filter main branch from the list of core releases to solve this on the drupal.org side, but we should also make the update parser more lenient in core.

nickdickinsonwilde’s picture

A temporary fix for existing sites is to uninstall the update module. That will make things work except for disabling update notifications.

longwave’s picture

I think this was fixed in 10.3 onwards with #3112962: Core compatibility messages on contrib available updates should consider supported branches - main is not marked as supported in the update XML, so it is filtered out before we try to compare it.

This doesn't help users on 10.2 and earlier where the fix still needs to be implemented server side.

nikky171091’s picture

A temporary fix either you uninstall the update module or go to

vendor\composer\semver\src\VersionParser.php

add one more condition after line number 109

if (null === $fullVersion) {
$fullVersion = $version;
}
+ if ($version === 'main'){return 'dev-main';}
// strip off aliasing

galooph’s picture

Confirmed on a site running 10.2.5. Disabling the update module did the trick \o/

longwave’s picture

To confirm, #3567494: Filter main branch from the list of core releases is deployed on the drupal.org side and the CDN is serving XML that no longer causes the crash, but it's possible that some sites will still have the XML cached locally in their update.module.

longwave’s picture

Status: Active » Fixed

Marking this as fixed, it's unfortunate this broke some older sites but the code path appears fine on 10.3 and above so there is nothing more for us to do here.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

cmlara’s picture

Status: Fixed » Active
Issue tags: +Security improvements

I disagree this is fixed.

There is a difference between accidentally avoided and a root cause solution.

The core updates.xml file is provided by a source outside of Drupal Core that is subject to:

  • Accidentally providing malformed data
  • Being intentionally hacked
  • Interception through a Man-In-The-Middle attack.

As an example if have 11.3.x deployed and add a 11.2.32.a.b.c. release to the update.xml the exception is still thrown taking down site administration with a WSOD.

Drupal Core must expect this to occur in the future and either provide validation of externally sourced data or exception handling.

Tested in 11.3.2 providing an intentionally malformed update.xml to Core (changed UpdateManager::buildFetchUrl() to pull from a local server for simulation purposes of either the 3 above incidents occurring)

<release>
      <name>drupal 11.3.1</name>
      <version>11.2.32.a.b.c</version>
      <tag>11.3.1</tag>
...
catch’s picture

Update module could either validate the version prior to comparison, or probably better: catch the exception and then log the exception message. Depends whether composer offers exactly the same validation it uses to throw that exception as a public API or not probably.

dww’s picture

Title: Update manager crashing admin panel » Update manager crashing admin panel with uncaught exceptions parsing version strings
Version: 10.2.x-dev » 11.x-dev
Issue tags: +Bug Smash Initiative
Related issues: +#3564803: Fatal error when unable to fetch release history

Yeah, these uncaught exceptions have really bothered me ever since the code that was throwing them was added to Update Status. Let's resolve that that before we call this issue fixed. A "faulty" or unexpected release history feed should never be able to crash a site. Sort of related to #3564803: Fatal error when unable to fetch release history in that sense.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

longwave’s picture

Status: Active » Needs review

Disclaimer: this MR was assisted by Claude Code.

jastraat’s picture

The MR worked to fix a recent issue when the Suggestion module made an alpha release with an invalid version constraint.

This could be any release for any module a site has installed that could take down the site if a module has a syntax error in the info file.

jastraat’s picture

Status: Needs review » Reviewed & tested by the community
dww’s picture

MR mostly looks good. 1 small question, but probably still RTBC.

Needs subsystem maintainer review 😉

dww’s picture

Status: Reviewed & tested by the community » Needs review

Oh yeah, also not sure about trying to log anything in the error cases. That’s probably a good idea. Only on my phone right now, not so easy to look around and propose specifics. But bumping back to NR for now.

longwave’s picture

Status: Needs review » Reviewed & tested by the community

Answered the question, back to RTBC!

dww’s picture

Status: Reviewed & tested by the community » Needs review

@longwave, what about #22? Can we log errors when we catch exceptions?

dww’s picture

I guess there’s nothing site admins can do to resolve these errors. So maybe logging them is pointless. But at least then there might be some evidence of a problem, folks could open issues in the upstream issue queues to get new releases.

However, I since we never remove releases, once a faulty release is in the feed, it’ll throw these exceptions forever.

I’m torn. Open to commit this as-is. But curious to get more discussion on this point.

longwave’s picture

Yeah there is nothing the site owner can do, so I think silently skipping bad data is probably the best thing?

dww’s picture

Probably, yeah. Since the site owner can’t fix it, it’s mostly only noise in their logs.

Meanwhile, haven’t tried it at all, but what happens if you install a release with a “bad” version? Does that cause an uncaught exception somewhere else? Or is parsing the feed the only spot this can happen?

dww’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new59.28 KB

Finally back home and had a chance to do more testing.

1. A "faulty" version string doesn't break update status. Putting this in a local test site's copy of address.info.yml:

version: main

results in:

Update status report with a version string set to 'main'

So that's fine, even in D10, etc. 🎉

2. The broken .info file from suggestion 4.2.0-alpha1 (referenced in comment #19) breaks a lot more than update status. Status report, extend page, and many others (not due to update_page_top() -- I removed that from my local test site) are all exploding along these lines:

Drupal\Core\Extension\InfoParserException: The 'core_version_requirement' constraint (^10 - drupal:block - drupal:field) is not a valid value in modules/contrib/address/address.info.yml in Drupal\Core\Extension\InfoParserDynamic->parse() (line 77 of core/lib/Drupal/Core/Extension/InfoParserDynamic.php).
Drupal\Core\Extension\InfoParser->parse('modules/contrib/address/address.info.yml') (Line: 551)
Drupal\Core\Extension\ExtensionList->createExtensionInfo(Object) (Line: 317)
Drupal\Core\Extension\ExtensionList->doList() (Line: 155)
Drupal\Core\Extension\ModuleExtensionList->doList() (Line: 283)
Drupal\Core\Extension\ExtensionList->getList() (Line: 109)

Not sure if we should be catching that exception and logging, or what. Maybe uncaught exceptions in this case are reasonable? Certainly fodder for a follow-up, not in scope here. But pointing out that broken .info.yml files impact a lot more of core than update status alone.

Given all that, moving this back to RTBC. The scope here of uncaught exceptions while parsing the update status feed are fixed by the current MR. Faulty .info.yml can still bring down a site, but that's for a follow-up (or an existing issue I haven't searched for, yet).

Thanks!
-Derek

jastraat’s picture

Just to be clear, we didn't have the version of the code with the faulty version installed.

It was merely that a module we were using on our site made a release with a faulty version. The update module automatically (scheduled cron job) pulled an XML file containing releases for the modules installed (including the faulty one) and the site started throwing 500 errors.

The 500 errors can be avoided by catching the exceptions.

dww’s picture

Re: #29 thanks. That was and is absolutely clear. That’s all the existing MR fixes. The point of my comment at the end of #27 and #28 was to wonder & investigate what else might be broken along similar lines, before I sign off on this bugfix. 😅 thankfully, the answer is “nothing else specific to Update Status, but potentially lots of other things that are out of scope here”. Hence, setting this to RTBC.

Thanks again,
-Derek

jastraat’s picture

Alrighty - thank you. Yes, I imagine this could have other implications. :/

  • catch committed 05b55eeb on 10.6.x
    fix: #3567483 Update manager crashing admin panel with uncaught...

  • catch committed 09ebcac3 on 11.x
    fix: #3567483 Update manager crashing admin panel with uncaught...

  • catch committed e808e76c on main
    fix: #3567483 Update manager crashing admin panel with uncaught...
catch’s picture

Version: main » 10.6.x-dev
Status: Reviewed & tested by the community » Fixed

This looks good.

Committed/pushed to main, 11.x, 11.4.x, and 10.6.x, thanks!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

  • catch committed f78790cb on 11.3.x
    fix: #3567483 Update manager crashing admin panel with uncaught...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.