<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Focus on your mission, not your tech - Another Cup of Coffee (Posts about Sys Admin)</title><link>https://anothercoffee.net/</link><description></description><atom:link href="https://anothercoffee.net/categories/sys-admin.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Copyright © 2006 - 2026 &lt;a href="https://anothercoffee.net/" title="Another Cup of Coffee Limited"&gt;Another Cup of Coffee Limited&lt;/a&gt; </copyright><lastBuildDate>Wed, 18 Feb 2026 16:39:44 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Fixing Access Forbidden (403) issues after migrating WordPress to a static site</title><link>https://anothercoffee.net/fixing-access-forbidden-403-issues-after-migrating-wordpress-to-a-static-site/</link><dc:creator>Anthony Lopez-Vito</dc:creator><description>&lt;p&gt;After migrating a WordPress site to static files, Google Search Console may start sending you notifications about page indexing problems. Often the issue will be marked as ‘&lt;em&gt;Blocked due to access forbidden (403)&lt;/em&gt;‘, a fairly common error that can have different causes, depending on how your website and server is set up.&lt;/p&gt;


&lt;figure class="figure d-flex flex-column align-items-center"&gt;
    &lt;img src="https://anothercoffee.net/images/no-entry-Lucian-Alexe-Unsplash-l0w1ftNPZ9s.jpg" alt="No entry road stock photo - Access Forbidden 403 error" class="figure-img img-fluid rounded" width="800" height="417"&gt;
&lt;/figure&gt;

&lt;p&gt;This article specifically deals with the case when:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You previously had a working WordPress installation;&lt;/li&gt;
&lt;li&gt;You migrate the site to static HTML files on an Apache web server;&lt;/li&gt;
&lt;li&gt;Google Search Console starts complaining about page indexing problems.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If this does not apply to your situation, the proposed solution may not work but you will still find the explanation useful in diagnosing the problem.&lt;/p&gt;
&lt;h2&gt;Table of contents&lt;/h2&gt;
&lt;div class="toc"&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/fixing-access-forbidden-403-issues-after-migrating-wordpress-to-a-static-site/#forbidden-403"&gt;The Forbidden 403 error&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/fixing-access-forbidden-403-issues-after-migrating-wordpress-to-a-static-site/#wordpress-requests"&gt;How WordPress serves your browser requests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/fixing-access-forbidden-403-issues-after-migrating-wordpress-to-a-static-site/#static-files"&gt;Serving static files&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/fixing-access-forbidden-403-issues-after-migrating-wordpress-to-a-static-site/#directory-index"&gt;Web server directory index&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/fixing-access-forbidden-403-issues-after-migrating-wordpress-to-a-static-site/#generating-static-site"&gt;Generating static HTML files from a WordPress site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/fixing-access-forbidden-403-issues-after-migrating-wordpress-to-a-static-site/#why-forbidden"&gt;Why access is forbidden&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/fixing-access-forbidden-403-issues-after-migrating-wordpress-to-a-static-site/#how-to-fix"&gt;How to fix the Access Forbidden (403) error&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

&lt;h2 id="forbidden-403"&gt;The Forbidden 403 error&lt;/h2&gt;
&lt;p&gt;Being in the 4XX category of HTTP response codes, &lt;em&gt;Access Forbidden (403)&lt;/em&gt; is a client-side error that may show in a message similar to the following combinations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Access Forbidden (403)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;403 Forbidden&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;HTTP 403&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;HTTP Error 403 – Forbidden&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Forbidden: You don’t have permission to access [directory path] on this server&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Google Search Console notification email will be about page indexing problems with  ‘&lt;em&gt;Blocked due to access forbidden (403)&lt;/em&gt;‘ as one of the Top Issues.&lt;/p&gt;

&lt;figure class="figure d-flex flex-column align-items-center"&gt;
    &lt;img src="https://anothercoffee.net/images/anothercoffee-google-search-console-page-indexing-issues.png" alt="Google Search Console Page indexing issues" class="figure-img img-fluid rounded" width="498" height="348"&gt;
    &lt;figcaption&gt;A typical Access Forbidden (403) notification from the Google Search Console&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Nevertheless, it being a client-side error doesn’t necessary isolate the problem to your browser. Many solutions online will advise you to clear your cache or refresh the page. This is easy to do and usually a sensible first step but if you found the issue via a Google Search Console notification after a WordPress migration, these recommendations won’t help.&lt;/p&gt;
&lt;p&gt;The 403 response code essentially means that a web client, such as your browser, does not have permission to access the requested resource. The web server understands the request but can’t allow access due to file permissions settings or a server misconfiguration. When it comes to WordPress, the error will almost certainly be due to a misbehaving plugin, a &lt;a href="https://kinsta.com/blog/403-forbidden-error/" target="_blank" rel="noreferrer noopener nofollow"&gt;corrupt .htaccess file or incorrect file permissions&lt;/a&gt;. However, if you’ve recently converted your WordPress installation to a static site, the error will most likely have a different cause.&lt;/p&gt;
&lt;p&gt;To understand why the &lt;em&gt;Access Forbidden&lt;/em&gt; error happens, it’s worth reviewing the differences between how the WordPress content management system (CMS) serves content and how a static site responds to web client requests.&lt;/p&gt;

&lt;h2 id="wordpress-requests"&gt;How WordPress serves your browser requests&lt;/h2&gt;
&lt;p&gt;WordPress is a database-driven Content management system (CMS). Most of the content is stored in a database and URLs generally do not correspond to any files in the web server’s filesystem. Instead, URLs are external references to the database content. WordPress calls these references &lt;em&gt;permalinks&lt;/em&gt; and its rewriting engine uses internal &lt;a href="https://codex.wordpress.org/Using_Permalinks"&gt;rules&lt;/a&gt;, specified in the &lt;a href="https://codex.wordpress.org/Using_Permalinks#Choosing_your_permalink_structure"&gt;permalink settings&lt;/a&gt;, to build permalinks dynamically. When a client requests a page from the site, WordPress takes care of serving the correct content. Included with the pages will be any XML-based RSS (Really Simple Syndication) feeds. WordPress will send the HTML page or an XML feed, depending on what the client requests.&lt;/p&gt;
&lt;p&gt;For example, if you set the permalink settings to the &lt;em&gt;Post name&lt;/em&gt; structure, WordPress will generate a HTML post when you browse to the following URL:&lt;br&gt;&lt;code&gt;https://example.com/your-post/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The RSS feed for that post will be at:&lt;br&gt;&lt;code&gt;https://example.com/your-post/feed/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;RSS feeds are normally parsed by an RSS client rather than for displaying directly in the browser window so requesting the RSS feed resource will not send HTML. Instead WordPress will generate XML for the feed.&lt;/p&gt;

&lt;h2 id="static-files"&gt;Serving static files&lt;/h2&gt;
&lt;p&gt;By definition, static sites have no way of dynamically generating content based on the browser request. You make a request to the web server at a given URL and if the resource is present with the correct access permissions, the web server will go ahead and serve the file. The URL for a static site will normally look something like:&lt;br&gt;&lt;code&gt;https://example.com/your-post.html&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you have an RSS feed, it might look something like:&lt;br&gt;&lt;code&gt;https://example.com/feed.xml&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Notice that the request includes the path to the file, such as &lt;code&gt;your-post.html&lt;/code&gt; or &lt;code&gt;feed.xml&lt;/code&gt;. The file is not present in a WordPress permalink because, as mentioned previously, it is only a reference to the actual content stored in the database.&lt;/p&gt;

&lt;h2 id="directory-index"&gt;Web server directory index&lt;/h2&gt;
&lt;p&gt;Web servers such as Apache also have a &lt;a href="https://httpd.apache.org/docs/2.4/mod/mod_dir.html#directoryindex" target="_blank" rel="noreferrer noopener nofollow"&gt;Directory Index directive&lt;/a&gt;. This is a configuration that can set the server to automatically send a file when a client makes a request without a filename in the URL. The file known as the directory index and is normally named &lt;code&gt;index.html&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Web servers such as Apache also have a &lt;a href="https://httpd.apache.org/docs/2.4/mod/mod_dir.html#directoryindex" target="_blank" rel="noreferrer noopener nofollow"&gt;Directory Index directive&lt;/a&gt;. In the early days of the web, you could browse to a folder in the web server filesystem and get a listing of all the files present. For security, most web hosts now disable this feature for most of their hosting services. The Directory Index directive is a configuration that can set the server to automatically send a file when a client request only includes the folder name in the URL. For most hosting services, the standard directory index files are normally &lt;code&gt;index.html&lt;/code&gt; and &lt;code&gt;index.php&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Say a client makes a request for the following:&lt;br&gt;&lt;code&gt;https://example.com/docs/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If the directory index is set to &lt;code&gt;index.html&lt;/code&gt;, the server would return:&lt;br&gt;&lt;code&gt;http://example.com/docs/index.html&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;index.html&lt;/code&gt; renders as a web page in the browser. Directory index resources can also be set to other file types like &lt;code&gt;index.txt&lt;/code&gt; or &lt;code&gt;index.xml&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id="generating-static-site"&gt;Generating static HTML files from a WordPress site&lt;/h2&gt;
&lt;p&gt;WordPress plugins such as &lt;a href="https://wordpress.org/plugins/simply-static/" target="_blank" rel="noreferrer noopener nofollow"&gt;Simply Static&lt;/a&gt; will crawl your site to generate static HTML file copies for the pages. Since WordPress includes RSS feeds, static XML copies will also be generated for these feeds. The tables below show typical WordPress permalinks and their equivalents after static HTML copies are generated.&lt;/p&gt;
&lt;figure class="wp-block-table"&gt;
&lt;table class="has-fixed-layout"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="width:30%"&gt;Page type&lt;/th&gt;
&lt;th&gt;WordPress permalink&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Page content&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;code&gt;https://example.com/your-post/&lt;/code&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSS feed&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;code&gt;https://example.com/your-post/feed/&lt;/code&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/figure&gt;
&lt;figure class="wp-block-table"&gt;
&lt;table class="has-fixed-layout"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="width:30%"&gt;Page type&lt;/th&gt;
&lt;th&gt;Static file URL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Page content&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;code&gt;https://example.com/your-post/index.html&lt;/code&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSS feed&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;code&gt;https://example.com/your-post/feed/index.xml&lt;/code&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/figure&gt;
&lt;p&gt;Once again notice that the static site specifies the filename in the path whereas the WordPress permalink, when set to the &lt;em&gt;Post name&lt;/em&gt; structure, does not.&lt;/p&gt;
&lt;h2 id="why-forbidden"&gt;Why access is forbidden&lt;/h2&gt;
&lt;p&gt;We have all the puzzle pieces to understand why you would get the &lt;em&gt;Access Forbidden (403)&lt;/em&gt; error and how you can fix the problem. After you migrate your WordPress site to static files, the old permalink paths to pages will still serve a web page because most hosting providers have &lt;code&gt;index.html&lt;/code&gt; as a directory index resource.&lt;/p&gt;
&lt;p&gt;You can request the URL in the WordPress post name permalink format:&lt;br&gt;&lt;code&gt;https://example.com/your-post/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The static file generator would have created an index.html in this location:&lt;br&gt;&lt;code&gt;https://example.com/your-post/&lt;/code&gt;index.html&lt;/p&gt;
&lt;p&gt;The webserver sees the &lt;code&gt;index.html&lt;/code&gt; in the filesystem and delivers it to the browser which can render the web page content. Human site visitors will be perfectly happy because they receive the web page resources they expect. However, Googlebot, Google’s web page crawler, will spider through your site &lt;em&gt;including the RSS feed locations&lt;/em&gt;. Remember, the RSS feed folders will contain an &lt;code&gt;index.xml&lt;/code&gt;. XML files are not normally a default directory index resource for most web hosts. Since there is no &lt;code&gt;index.html&lt;/code&gt; file in the feed folder, the web server thinks it’s being asked to deliver a file listing. Again remember that file listings are disabled by most web hosts for security. Thus you get the error:&lt;/p&gt;
&lt;p class="has-text-align-center"&gt;&lt;code&gt;Access Forbidden (403)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;You are forbidden by the web server to access that folder listing.&lt;/p&gt;

&lt;h2 id="how-to-fix"&gt;How to fix the Access Forbidden (403) error&lt;/h2&gt;
&lt;p&gt;Now that we know exactly why we get this error we attempt a fix. If your host runs Apache, the solution will likely be simple. Edit or create the &lt;code&gt;.htaccess&lt;/code&gt; file in the root of your site and add &lt;code&gt;index.xml&lt;/code&gt; to the list of directory index resources. For example, if it not already there, add the following line somewhere near the top of the file:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;DirectoryIndex index.html index.php index.xml&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;index.xml&lt;/code&gt; in the list will tell Apache to serve the XML file when Googlebot requests the RSS feed directory. While you’re doing this, inspect a few o the feed directories to make sure the &lt;code&gt;index.xml&lt;/code&gt; files have the correct permissions (usually &lt;code&gt;775&lt;/code&gt; for most server setups) and the correct ownership. The ownership settings should be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;user&lt;/code&gt;&lt;/strong&gt; is the user account with root privileges on your web server.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;group&lt;/code&gt;&lt;/strong&gt; is usually &lt;strong&gt;&lt;code&gt;www-data&lt;/code&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;code&gt;apache&lt;/code&gt;&lt;/strong&gt; but you may need to check this with your hosting provider.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can test your changes by pointing your browser to a few feed directories to see if the server returns XML. Remember to leave out the &lt;code&gt;index.xml&lt;/code&gt; file and specify the directory only. For example:&lt;br&gt;&lt;code&gt;https://example.com/your-post/feed/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If your browser displays the RSS feed XML, you know the problem has been solved and can be reasonably confident that Googlebot won’t encounter the 403 error.&lt;/p&gt;
&lt;p&gt;This may not work if you’re running a VPS server for your site where some more in-depth configuration may be needed, such as editing your Apache configuration files. Also, &lt;code&gt;.htaccess&lt;/code&gt; is not used by other web servers such as NGINX. In these cases, your next port of call should be to contact your hosting provider. Tell them that you would like to add &lt;code&gt;index.xml&lt;/code&gt; to the directory index resources so that the XML file is served when a visitor lands in a directory. Most good hosting companies will be able to guide you on your options or make the change on your behalf. After you’ve applied the fix, be sure to go to your Google Search Console to revalidate the affected page.&lt;/p&gt;

&lt;div class="footnotes"&gt;
    &lt;p&gt;Photo by &lt;a href="https://unsplash.com/@lucian_alexe?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" target="_blank" rel="nofollow"&gt;Lucian Alexe&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/l0w1ftNPZ9s?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" target="_blank" rel="nofollow"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;hr&gt;

&lt;section class="mt-4 pt-4"&gt;
    &lt;h2&gt;You may also like&lt;/h2&gt;

    &lt;div class="row"&gt;

        &lt;div class="col-md-6 col-lg-4 mb-4"&gt;
            &lt;div class="card h-100"&gt;
                &lt;a href="https://anothercoffee.net/drupal-to-wordpress-migration-guide/"&gt;
                        &lt;img src="https://anothercoffee.net/images/drupal-to-wordpress-migration-utilities-featured.jpg" class="card-img-top" alt="Drupal to WordPress Migration Guide"&gt;&lt;/a&gt;
                &lt;div class="card-body d-flex flex-column"&gt;
                    &lt;h5 class="card-title"&gt;&lt;a href="https://anothercoffee.net/drupal-to-wordpress-migration-guide/" class="listtitle"&gt;Drupal to WordPress Migration Guide&lt;/a&gt;&lt;/h5&gt;
                    &lt;div class="mb-2"&gt;
                        &lt;span&gt;&lt;time class="listdate" datetime="2025-01-03T15:30:30Z" title="Updated for 2025"&gt;Updated for 2025&lt;/time&gt;&lt;/span&gt;
                    &lt;/div&gt;
                    &lt;p class="card-text flex-grow-1"&gt;In this guide, you'll find insights drawn from almost 15 years of specialising in complex Drupal to WordPress migration projects. I'll walk you through the entire migration process, from the initial evaluation to post-launch considerations.&lt;/p&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;

        &lt;div class="col-md-6 col-lg-4 mb-4"&gt;
            &lt;div class="card h-100"&gt;
                &lt;a href="https://anothercoffee.net/secure-your-ai-workflow-using-local-tokenisation/"&gt;
                        &lt;img src="https://anothercoffee.net/images/Secure-your-AI-workflow-using-local-tokenisation-in-PaigeSafe-featured.jpg" class="card-img-top" alt="Secure Your AI Workflow Using Local Tokenisation"&gt;&lt;/a&gt;
                &lt;div class="card-body d-flex flex-column"&gt;
                    &lt;h5 class="card-title"&gt;&lt;a href="https://anothercoffee.net/secure-your-ai-workflow-using-local-tokenisation/" class="listtitle"&gt;Secure Your AI Workflow Using Local Tokenisation&lt;/a&gt;&lt;/h5&gt;
                    &lt;div class="mb-2"&gt;
                        &lt;span&gt;&lt;time class="listdate" datetime="2024-11-12T13:59:03Z" title="12 November 2024"&gt;12 November 2024&lt;/time&gt;&lt;/span&gt;
                    &lt;/div&gt;

                        &lt;p class="card-text flex-grow-1"&gt;Don't leak confidential client data when using cloud-based LLMs. Secure your AI workflow with local tokenisation using PaigeSafe.&lt;/p&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;

        &lt;div class="col-md-6 col-lg-4 mb-4"&gt;
            &lt;div class="card h-100"&gt;
                &lt;a href="https://anothercoffee.net/drupal-7-docker-containers-migration-projects/"&gt;
                        &lt;img src="https://anothercoffee.net/images/posts/Drupal-Docker-Containers-card-300-150.jpg" class="card-img-top" alt="How To Set Up Drupal 7 Docker Containers for Migration Projects"&gt;&lt;/a&gt;
                &lt;div class="card-body d-flex flex-column"&gt;
                    &lt;h5 class="card-title"&gt;&lt;a href="https://anothercoffee.net/drupal-7-docker-containers-migration-projects/" class="listtitle"&gt;How To Set Up Drupal 7 Docker Containers for Migration Projects&lt;/a&gt;&lt;/h5&gt;
                    &lt;div class="mb-2"&gt;
                        &lt;span&gt;&lt;time class="listdate" datetime="2024-09-09T13:25:15Z" title="09 September 2024"&gt;09 September 2024&lt;/time&gt;&lt;/span&gt;
                    &lt;/div&gt;

                        &lt;p class="card-text flex-grow-1"&gt;Learn how Docker is a valuable tool for Drupal 7 end of life migrations. In this post, I'll give a step-by-step guide to setting up a Drupal 7 container for your migration project.&lt;/p&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

&lt;/section&gt;</description><category>Apache</category><category>Blog</category><category>Help</category><category>Migration</category><category>SEO</category><category>Sys Admin</category><category>Troubleshooting</category><category>WordPress</category><guid>https://anothercoffee.net/fixing-access-forbidden-403-issues-after-migrating-wordpress-to-a-static-site/</guid><pubDate>Thu, 09 Feb 2023 01:15:57 GMT</pubDate></item><item><title>How to set up a MySQL database server on Ubuntu for Drupal to WordPress migrations</title><link>https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/</link><dc:creator>Anthony Lopez-Vito</dc:creator><description>&lt;p&gt;Content Management System (CMS) migration projects involve moving data between databases with different schemas. Table names, field types and constraints often don’t match up, leading to a number of &lt;a href="https://anothercoffee.net/tag/troubleshooting/"&gt;frustrating errors&lt;/a&gt;. This is especially the case with &lt;a href="https://anothercoffee.net/content-migration-process/"&gt;highly complex Drupal to WordPress migrations&lt;/a&gt; that use custom scripts to extract, transform and load the data. These projects can seem like you’re constantly hitting roadblocks throughout. I’ve found from experience that running the migration in an appropriate development environment can reduce a great deal of effort. In this guide, I will describe how to set up a MySQL database server on Ubuntu for Drupal to WordPress migrations.&lt;/p&gt;

&lt;figure class="figure d-flex flex-column align-items-center"&gt;
    &lt;img src="https://anothercoffee.net/images/rubaitul-azad-Y9kOsyoWyaU-unsplash.jpg" alt="MySQL database logo" class="figure-img img-fluid rounded" width="800" height="500"&gt;
&lt;/figure&gt;

&lt;h2 id="drupal-to-wordPress-mysql-server-toc"&gt;Table of contents&lt;/h2&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/#why-mysql-ubuntu"&gt;Why MySQL and Ubuntu?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/#installing-mysql-for-migrations"&gt;Installing MySQL on Ubuntu for CMS migrations&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/#setup-lamp-migration-platform"&gt;Set up your Ubuntu LAMP migration platform&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/#install-mysql"&gt;Install MySQL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/#setting-sql-mode"&gt;Setting the MySQL server SQL mode&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/#set-global-sql-mode"&gt;Option 1: Setting the global sql_mode in the database&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/#set-mysql-config-file"&gt;Option 2: setting the sql_mode in the MySQL configuration file&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/#locating-mysql-conf"&gt;Locating the MySQL configuration file&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/#edit-mysql-config-file"&gt;Editing the MySQL configuration file&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/#potential-errors"&gt;Potential errors&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/#mysqldump-access-denied-when-trying-to-dump-tablespaces"&gt;mysqldump access denied when trying to dump tablespaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/#ERROR-1067-42000-Invalid-default-value"&gt;ERROR 1067 (42000) Invalid default value&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/#Expression-1-of-SELECT-list-is-not-in-GROUP-BY-clause"&gt;Expression #1 of SELECT list is not in GROUP BY clause&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/#Error-Code-2013-Lost-connection-to-MySQL-server"&gt;Error Code: 2013. Lost connection to MySQL server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/#conclusion"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;h2 id="why-mysql-ubuntu"&gt;Why MySQL and Ubuntu?&lt;/h2&gt;
&lt;p&gt;The first thing to address is &lt;em&gt;why MySQL and Ubuntu?&lt;/em&gt; How about MariaDB? How about Arch Linux, Mac OS or Windows? Yes! Any platform that runs Drupal and WordPress will work for your migration environment so you can use whatever you prefer. Personally, I have a fondness for &lt;a href="https://www.openbsd.org/" target="_blank" rel="noreferrer noopener"&gt;OpenBSD&lt;/a&gt; but it’s not a practical platform for a CMS migration. OpenBSD’s niche user-base means you’ll spend much longer installing necessary tools and troubleshooting errors.&lt;/p&gt;
&lt;p&gt;There are all sorts of tutorials covering MySQL on Ubuntu. This means you’re more likely to quickly find a solution from a web search when you hit a problem. Furthermore, if you need a software utility or program to help you get the job done, it will probably be available through &lt;code&gt;apt&lt;/code&gt;, &lt;code&gt;dpkg&lt;/code&gt;,  &lt;code&gt;snap&lt;/code&gt; or &lt;code&gt;tasksel&lt;/code&gt;. Use whatever you like but for now, MySQL on Ubuntu is my recommended platform for Drupal to WordPress migrations. I expect this will be the case for some time to come. These projects are complex and time-consuming enough without making the &lt;a href="https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/#mariadb-mysql-purge"&gt;job more difficult&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id="installing-mysql-for-migrations"&gt;Installing MySQL on Ubuntu for CMS migrations&lt;/h2&gt;
&lt;p&gt;There are many detailed tutorials for installing MySQL on Ubuntu. DigitalOcean’s &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-mysql-on-ubuntu-20-04" target="_blank" rel="noreferrer noopener nofollow"&gt;How To Install MySQL on Ubuntu 20.04&lt;/a&gt; is a good one and writing another won’t add much value. My guide will therefore only give a brief overview of the MySQL server installation steps. Instead, I will focus on the configuration areas specifically related avoiding problems on a CMS migration project.&lt;/p&gt;
&lt;p&gt;You may wonder why the migration environment should be much different from a live server. Migration projects require you to do things that aren’t supported by the CMS platform. You’re therefore likely to encounter &lt;a href="https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/#potential-errors"&gt;weird errors&lt;/a&gt; that aren’t normally found when running standard Drupal or WordPress.&lt;/p&gt;

&lt;h3 id="setup-lamp-migration-platform"&gt;Set up your Ubuntu LAMP migration platform&lt;/h3&gt;
&lt;p&gt;The main source of unusual errors is almost certainly because you’re migrating on a setup suited to a live website. Live server configurations are more restrictive than you need for a migration project. You can therefore save yourself a huge headache by rolling your own local migration environment. It might take a little longer to get started but you’ll save time by avoiding lots of unnecessary troubleshooting.&lt;/p&gt;
&lt;p&gt;I must highlight that this will be a &lt;em&gt;local migration environment&lt;/em&gt; and should not be accessible from the public internet. The normal security considerations with running a live content management system don’t apply when you’re working locally. By all means follow basic security measures mentioned the various tutorials for setting up Ubuntu and MySQL. Nevertheless, a highly secure setup is counterproductive for these projects and you can avoid trouble by being a little more permissive.&lt;/p&gt;
&lt;p&gt;Go ahead and &lt;a href="https://ubuntu.com/tutorials/install-ubuntu-desktop" target="_blank" rel="noreferrer noopener"&gt;install Ubuntu Desktop&lt;/a&gt;. Since this will be a development environment, you’ll want the Desktop environment rather than the more lightweight server version. Of course, you’ll still need to install a web and database server. &lt;a href="https://upcloud.com/community/tutorials/installing-lamp-stack-ubuntu/" target="_blank" rel="noreferrer noopener"&gt;Follow these instructions for installing LAMP stack&lt;/a&gt; but skip the step of installing MariaDB. As mentioned above, we’ll be using MySQL.&lt;/p&gt;


&lt;div id="mariadb-mysql-purge" class="alert alert-warning"&gt;
&lt;p class="has-text-align-left"&gt;&lt;strong&gt;WARNING:&lt;/strong&gt; Installing MariaDB over MySQL or vice versa on Ubuntu 20.04 may lead to all sorts of &lt;a href="https://askubuntu.com/questions/1300304/mysql-not-working-after-uninstall-mariadb-in-ubuntu" target="_blank" rel="noreferrer noopener"&gt;problems starting up the database server&lt;/a&gt; with errors like the following:&lt;/p&gt;
&lt;p class="has-text-align-left"&gt;&lt;code&gt;Failed to start mysqld.service: Unit mysqld.service not found&lt;/code&gt;.&lt;/p&gt;
&lt;p class="has-text-align-left"&gt;The last time I did this, none of solutions mentioned online for purging the installation worked. I spent most of a day trying to fix the problem. In the end, I realised it was quicker to start again and rebuild the machine from scratch. This is a big reason why I decided to stick with MySQL as standard for my projects.&lt;/p&gt;
&lt;/div&gt;

&lt;h3 id="install-mysql"&gt;Install MySQL&lt;/h3&gt;
&lt;p&gt;You can read a more detailed tutorial on &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-mysql-on-ubuntu-20-04" target="_blank" rel="noreferrer noopener"&gt;installing MySQL on Ubuntu&lt;/a&gt; but here’s an overview.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Update the package index on your server: &lt;code&gt;sudo apt update&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Install MySQL server: &lt;code&gt;sudo apt install mysql-server&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Secure MySQL: &lt;code&gt;sudo /usr/bin/mysql_secure_installation&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;code&gt;mysql_secure_installation&lt;/code&gt; script doesn’t cause problems for migrations so it’s worth running.&lt;/p&gt;
&lt;p&gt;Create an admin user:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE USER ‘user’@'localhost’ IDENTIFIED BY ‘userpassword’;
GRANT ALL PRIVILEGES ON *.* to ‘user’@'localhost’ WITH GRANT OPTION;
FLUSH PRIVILEGES;
quit;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now create a user and database for your migration project:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE USER ‘projectuser’@'localhost’ IDENTIFIED BY ‘password’;

CREATE DATABASE project_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci;
GRANT ALL ON project_db.* TO ‘projectuser’@'localhost’;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can give this user more restrictive permissions but &lt;code&gt;GRANT ALL&lt;/code&gt; avoids errors when running scripts and SQL queries on the database. Only the migration team should have access and you won’t need it after the migration so why not make your life easier? &lt;/p&gt;

&lt;h2 id="setting-sql-mode"&gt;Setting the MySQL server SQL mode&lt;/h2&gt;
&lt;p&gt;It’s possible that you won’t be familiar with &lt;a href="https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html" target="_blank" rel="noreferrer noopener"&gt;SQL modes&lt;/a&gt; unless you’ve done some database administration work. For our purposes, SQL modes do two things:&lt;/p&gt;


&lt;ul&gt;
&lt;li&gt;change the types of queries you can run on your MySQL server;&lt;/li&gt;
&lt;li&gt;change the validation checks when altering the data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ve found that specific SQL modes need to be set for Drupal to WordPress projects. You may find that all sorts of strange errors appear if the correct modes aren’t set. The following sections show you two ways to set your MySQL server’s SQL mode.&lt;/p&gt;

&lt;h3 id="set-global-sql-mode"&gt;Option 1: Setting the global sql_mode in the database&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Login in to database as an admin user.&lt;/li&gt;
&lt;li&gt;View the current sql-modes using &lt;code&gt;SELECT @@GLOBAL.sql_mode;&lt;/code&gt; and make a copy if necessary.&lt;/li&gt;
&lt;li&gt;Copy the current modes (add or delete modes as needed) and paste in next step.&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;ALLOW_INVALID_DATES&lt;/code&gt; and removes both &lt;code&gt;NO_ZERO_DATE, NO_ZERO_IN_DATE&lt;/code&gt; by setting the sql-modes with&lt;br&gt;&lt;code&gt;SET GLOBAL sql_mode = ‘STRICT_TRANS_TABLES,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION’;&lt;/code&gt; (WARNING: check the modes correspond with your setup.)&lt;/li&gt;
&lt;li&gt;Restart server:&lt;br&gt;&lt;code&gt;sudo systemctl start mysql&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id="set-mysql-config-file"&gt;Option 2: setting the sql_mode in the MySQL configuration file&lt;/h3&gt;
&lt;h4 id="locating-mysql-conf"&gt;Locating the MySQL configuration file&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;my.cnf&lt;/code&gt; configuration file isn’t always found in the same place. It’s specific to the Linux distribution and server configuration but can normally found in one of the following locations:&lt;/p&gt;
&lt;pre class="wp-block-preformatted"&gt;/etc/my.cnf
/etc/mysql/my.cnf
echo/my.cnf
[datadir]/my.cnf
~/.my.cnf&lt;/pre&gt;

&lt;p&gt;If you can’t find your MySQL configuration file, you can try running &lt;code&gt;locate my.cnf&lt;/code&gt; or &lt;code&gt;mysqladmin –help&lt;/code&gt;. The latter will show something like the following in the output:&lt;/p&gt;

&lt;pre class="wp-block-preformatted"&gt;Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf&lt;/pre&gt;
&lt;p&gt;Also keep in mind that it’s possible to use &lt;code&gt;!include&lt;/code&gt; directives to include other &lt;a href="https://dev.mysql.com/doc/refman/8.0/en/option-files.html" rel="noreferrer noopener" target="_blank"&gt;option files&lt;/a&gt; and &lt;code&gt;!includedir&lt;/code&gt; to search specific directories for option files. Under Ubuntu, there may be a file &lt;code&gt;/etc/mysql/my.cnf&lt;/code&gt; with &lt;code&gt;!includedir&lt;/code&gt; directives to search &lt;code&gt;/etc/mysql/conf.d/&lt;/code&gt; and &lt;code&gt;/etc/mysql/mysql.conf.d/&lt;/code&gt;&lt;/p&gt;


&lt;h4 id="edit-mysql-config-file"&gt;Editing the MySQL configuration file&lt;/h4&gt;
&lt;p&gt;If the MySQL server finds more than one configuration file, it will load each one in turn. The values override each other and it can be difficult to know which takes priority. Furthermore, the &lt;code&gt;–defaults-file&lt;/code&gt; parameter can also override all configurations. Keep things simple and have only one file and place it the directory that makes sense to you.&lt;/p&gt;
&lt;p&gt;Before editing the &lt;code&gt;my.cnf&lt;/code&gt;, first log in to MySQL with an administrator user and run the &lt;code&gt;SELECT @@GLOBAL.sql_mode&lt;/code&gt; query to see the values used in your setup.&lt;/p&gt;

&lt;figure class="wp-block-image size-full"&gt;&lt;img src="https://anothercoffee.net/images/drupal-to-wordpress-mysql-select-global-sql_mode.jpg" alt="Setting the MySQL database server sql mode on Ubuntu for Drupal to WordPress migrations" class="wp-image-3705"&gt;&lt;br&gt;
&lt;figcaption class="wp-element-caption"&gt;&lt;em&gt;Running the &lt;code&gt;SELECT @@GLOBAL.sql_mode&lt;/code&gt; query on MySQL Workbench&lt;/em&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Next, open the configuration file, look for the section &lt;code&gt;[mysqld]&lt;/code&gt; and edit the line starting with:&lt;br&gt;&lt;code&gt;sql_mode = …&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add the line if it’s not there. Adjust the exact modes to match your project’s needs so take a look at the &lt;a href="https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sql-mode-full" target="_blank" rel="noreferrer noopener"&gt;list of SQL modes&lt;/a&gt; to see which may apply. I’ve found the following works well:&lt;br&gt;&lt;code&gt;sql_mode = “STRICT_TRANS_TABLES,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION”&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Finally, restart the MySQL server. On Ubuntu this will probably be with&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo systemctl start mysql&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If you are logged in to the MySQL server, you may also need to disconnect your client and reconnect for the changes to take effect for your session.&lt;/p&gt;

&lt;h2 id="potential-errors"&gt;Potential errors&lt;/h2&gt;
&lt;p&gt;Here are some potential errors that you may come across during a CMS migration project. I usually find them when running a Drupal to WordPress migration on a freshly built development environment.&lt;/p&gt;
&lt;h3 id="mysqldump-access-denied-when-trying-to-dump-tablespaces"&gt;mysqldump access denied when trying to dump tablespaces&lt;/h3&gt;
&lt;p&gt;Migrations involve dumping and importing databases and this process is straightforward on a mature development environment. However you may receive an ‘Access denied’ error out of the blue when dumping your MySQL database:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mysqldump: Error: ‘Access denied; you need (at least one of) the PROCESS privilege(s) for this operation’ when trying to dump tablespaces&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If you see this, perhaps you were working on an environment that was a little too ‘mature’ (in other words, obsolete!) and you have recently upgraded your installation. The updates for MySQL 5.7.31 and MySQL 8.0.21 in July 2020 introduced an incompatible change that produces this error.&lt;/p&gt;
&lt;p&gt;Read my separate article, &lt;a href="https://anothercoffee.net/how-to-fix-the-mysqldump-access-denied-process-privilege-error/"&gt;How to fix the mysqldump access denied process privilege error&lt;/a&gt;, for more information and instructions on how you can try solving this.&lt;/p&gt;
&lt;h3 id="ERROR-1067-42000-Invalid-default-value"&gt;ERROR 1067 (42000) Invalid default value&lt;/h3&gt;
&lt;p&gt;Drupal nodes store the date as a Unix timestamp in an &lt;code&gt;int&lt;/code&gt; (e.g. &lt;code&gt;1623427200&lt;/code&gt;) field whereas WordPress stores dates as &lt;code&gt;&lt;a href="https://dev.mysql.com/doc/refman/8.0/en/datetime.html" target="_blank" rel="noreferrer noopener nofollow"&gt;datetime&lt;/a&gt;&lt;/code&gt; (e.g. &lt;code&gt;2021-06-11 16:00:00&lt;/code&gt;). There may be a conversion error in your migration script or the source date could simply be zero for some reason. Normally your MySQL server mode will be set to &lt;code&gt;NO_ZERO_DATE, NO_ZERO_IN_DATE&lt;/code&gt; so trying to insert a zero date will give you the error:&lt;/p&gt;
&lt;pre class="wp-block-preformatted"&gt;&lt;code&gt;ERROR 1067 (42000) Invalid default value&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can fix this by replacing &lt;code&gt;NO_ZERO_DATE, NO_ZERO_IN_DATE&lt;/code&gt;  with set to &lt;code&gt;ALLOW_INVALID_DATES&lt;/code&gt; in your global SQL mode.&lt;/p&gt;

&lt;h3 id="Expression-1-of-SELECT-list-is-not-in-GROUP-BY-clause"&gt;Expression #1 of SELECT list is not in GROUP BY clause&lt;/h3&gt;
&lt;p&gt;You run an SQL query and get the rather cryptic error:&lt;/p&gt;
&lt;pre class="wp-block-preformatted"&gt;Expression #1 of SELECT list is not in GROUP BY clause and contains
nonaggregated column ‘database.table.pid’ which is not functionally dependent
on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by&lt;/pre&gt;
&lt;p&gt;What’s wrong? MySQL has a &lt;code&gt;only_full_group_by&lt;/code&gt; mode which, when enabled, strictly applies ANSI SQL rules when using &lt;code&gt;GROUP BY&lt;/code&gt;. Fix this by reworking your script or removing the &lt;code&gt;ONLY_FULL_GROUP_BY&lt;/code&gt; SQL mode.&lt;/p&gt;

&lt;h3 id="Error-Code-2013-Lost-connection-to-MySQL-server"&gt;Error Code: 2013. Lost connection to MySQL server&lt;/h3&gt;
&lt;p&gt;This often happens when it an SQL query takes too long to return data. The connection between your MySQL client and database server times out so the connection gets dropped. For ideas on how to try solving this, read my separate article, &lt;a href="https://anothercoffee.net/fix-error-code-2013-lost-connection-mysql-server-query/"&gt;How to fix Error Code 2013 Lost connection to MySQL server&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Setting up a MySQL database server for Drupal or WordPress is a familiar task for web developers and site administrators.  However, CMS migrations have quirks that can cause obscure and baffling errors. In this guide I’ve shown you some little tricks that may save time and annoyance. While there’s no way to provide an exhaustive list of solutions to all the MySQL problems you’ll encounter, I hope to have pointed you in the right direction.&lt;/p&gt;
&lt;p&gt;If you have a site migration project and would like to hire me, please &lt;a href="https://anothercoffee.net/#contact"&gt;ask for a quote&lt;/a&gt; for my consulting service.&lt;/p&gt;

&lt;div class="alert alert-info text-center" style="margin: 100px 0 100px 0; padding-bottom:20px;"&gt;
&lt;h3 style="font-size: 1.5em;"&gt;&lt;a title="CMS migration" href="https://anothercoffee.net/drupal-to-wordpress-migration-service/"&gt;CMS migration consulting&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;All content · Custom content types · SEO · Plugins&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Migrating content from a site and need a specialist? Please &lt;a title="Get an estimate for site migration" href="https://anothercoffee.net/#contact"&gt;contact me&lt;/a&gt; for a quotation.&lt;/em&gt; Whether you’re a media agency who needs a database expert or a site owner looking for advice, I’ll save you time and ensure accurate content exports.&lt;/p&gt;

&lt;button class="cta-button"&gt;&lt;a href="https://anothercoffee.net/#contact"&gt;Get a quote&lt;/a&gt;&lt;/button&gt;

&lt;/div&gt;



&lt;div class="footnotes"&gt;
    &lt;p&gt;Cover photo by &lt;a href="https://unsplash.com/@rubaitulazad?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Rubaitul Azad&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/text-Y9kOsyoWyaU?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="nofollow"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;hr&gt;

&lt;section class="mt-4 pt-4"&gt;
    &lt;h2&gt;You may also like&lt;/h2&gt;

    &lt;div class="row"&gt;

        &lt;div class="col-md-6 col-lg-4 mb-4"&gt;
            &lt;div class="card h-100"&gt;
                &lt;a href="https://anothercoffee.net/drupal-to-wordpress-migration-guide/"&gt;
                        &lt;img src="https://anothercoffee.net/images/drupal-to-wordpress-migration-utilities-featured.jpg" class="card-img-top" alt="Drupal to WordPress Migration Guide"&gt;&lt;/a&gt;
                &lt;div class="card-body d-flex flex-column"&gt;
                    &lt;h5 class="card-title"&gt;&lt;a href="https://anothercoffee.net/drupal-to-wordpress-migration-guide/" class="listtitle"&gt;Drupal to WordPress Migration Guide&lt;/a&gt;&lt;/h5&gt;
                    &lt;div class="mb-2"&gt;
                        &lt;span&gt;&lt;time class="listdate" datetime="2025-01-03T15:30:30Z" title="Updated for 2025"&gt;Updated for 2025&lt;/time&gt;&lt;/span&gt;
                    &lt;/div&gt;
                    &lt;p class="card-text flex-grow-1"&gt;In this guide, you'll find insights drawn from almost 15 years of specialising in complex Drupal to WordPress migration projects. I'll walk you through the entire migration process, from the initial evaluation to post-launch considerations.&lt;/p&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;

        &lt;div class="col-md-6 col-lg-4 mb-4"&gt;
            &lt;div class="card h-100"&gt;
                &lt;a href="https://anothercoffee.net/secure-your-ai-workflow-using-local-tokenisation/"&gt;
                        &lt;img src="https://anothercoffee.net/images/Secure-your-AI-workflow-using-local-tokenisation-in-PaigeSafe-featured.jpg" class="card-img-top" alt="Secure Your AI Workflow Using Local Tokenisation"&gt;&lt;/a&gt;
                &lt;div class="card-body d-flex flex-column"&gt;
                    &lt;h5 class="card-title"&gt;&lt;a href="https://anothercoffee.net/secure-your-ai-workflow-using-local-tokenisation/" class="listtitle"&gt;Secure Your AI Workflow Using Local Tokenisation&lt;/a&gt;&lt;/h5&gt;
                    &lt;div class="mb-2"&gt;
                        &lt;span&gt;&lt;time class="listdate" datetime="2024-11-12T13:59:03Z" title="12 November 2024"&gt;12 November 2024&lt;/time&gt;&lt;/span&gt;
                    &lt;/div&gt;

                        &lt;p class="card-text flex-grow-1"&gt;Don't leak confidential client data when using cloud-based LLMs. Secure your AI workflow with local tokenisation using PaigeSafe.&lt;/p&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;

        &lt;div class="col-md-6 col-lg-4 mb-4"&gt;
            &lt;div class="card h-100"&gt;
                &lt;a href="https://anothercoffee.net/drupal-7-docker-containers-migration-projects/"&gt;
                        &lt;img src="https://anothercoffee.net/images/posts/Drupal-Docker-Containers-card-300-150.jpg" class="card-img-top" alt="How To Set Up Drupal 7 Docker Containers for Migration Projects"&gt;&lt;/a&gt;
                &lt;div class="card-body d-flex flex-column"&gt;
                    &lt;h5 class="card-title"&gt;&lt;a href="https://anothercoffee.net/drupal-7-docker-containers-migration-projects/" class="listtitle"&gt;How To Set Up Drupal 7 Docker Containers for Migration Projects&lt;/a&gt;&lt;/h5&gt;
                    &lt;div class="mb-2"&gt;
                        &lt;span&gt;&lt;time class="listdate" datetime="2024-09-09T13:25:15Z" title="09 September 2024"&gt;09 September 2024&lt;/time&gt;&lt;/span&gt;
                    &lt;/div&gt;

                        &lt;p class="card-text flex-grow-1"&gt;Learn how Docker is a valuable tool for Drupal 7 end of life migrations. In this post, I'll give a step-by-step guide to setting up a Drupal 7 container for your migration project.&lt;/p&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

&lt;/section&gt;</description><category>Blog</category><category>Database</category><category>Drupal</category><category>Help</category><category>Migration</category><category>MySQL</category><category>Sys Admin</category><category>Troubleshooting</category><category>WordPress</category><guid>https://anothercoffee.net/how-to-set-up-a-mysql-database-server-on-ubuntu-for-drupal-to-wordpress-migrations/</guid><pubDate>Fri, 11 Jun 2021 15:44:52 GMT</pubDate></item></channel></rss>