Troubleshooting ‘The provided URL does not represent a valid oEmbed resource.’ with YouTube videos

If you are trying to add a YouTube video using media > remote video in Drupal 8.7 (media is now part of core) and you stumble across this error – which is not discussed anywhere in the core issue queue that I can see…

The provided URL does not represent a valid oEmbed resource.

the fix is to add this line in settings.php:

$settings['http_client_config']['force_ip_resolve'] = 'v4';

Debugging / cause:

– First verify it’s not a private video (unlisted is fine)
– Optionally you can manually test the oEmbed response in your browser (you should get some JSON data back) – the URL needs to be:
https://www.youtube.com/ombed?url=[an encoded full YouTube URL]

It’s as quick/quicker to look in Recent Log Messages in Drupal first, you may be seeing errors like this:

Client error: `GET https://www.youtube.com/oembed?url=https%3A//www.youtube.com/watch%3Fv%3Dyoutubeid` resulted in a `429 Too Many Requests` response:

and also:

Could not retrieve the oEmbed resource.

(which doesn’t tell you anything).

oEmbed requests in Drupal are simple, unauthenticated HTTP GETs – i.e. they don’t use the YouTube API.  Nothing particularly wrong about this.  However the trouble is YouTube has started blocking IPv6 blocks en-mass; apparently because it’s too easy for people to keep changing IPv6 addresses (if ISPs provide a large pool of them) and use them for spam.   Therefore all and any requests over IPv6 may simply be blocked, regardless of how few you’ve made (I can confirm this for Linode servers.)

First, verify this is true for your server by manually grabbing the URL at the command line via wget, with the  -6 and -4 switches.

Assuming IPv4 works, you now need to tell Drupal to make Drupal use it.  This is easier than expected.   Drupal uses the Guzzle HTTP client library, specifically as an HTTP client factory – but as this StackExchange answer explains  – part of the default setup automatically merges in values from $settings, i.e. anything you add under $settings[‘http_client_config’].

So make your $settings.php writeable, and configure the force_ip_resolve setting as shown at the beginning of this post.

YouTube queries should then start working immediately.