How can I create 301 redirects from "unclean" URLs? I am moving a Wordpress site to Drupal and want to ensure that proper 301 redirects are in place for SEO purposes. 

The old urls are in the form of: http:www.domain.com/?page_id=123

I was hoping this would be simple enough with the Redirect module, but when attempting to enter a path such as ?page_id=123 I see the following message.


  The source path /?page_id=123 is likely a valid path. It is preferred to create URL aliases for existing paths rather than redirects.


I want to be absolutely sure that a 301 redirect is created but I am unsure that adding an alias is the correct method for this.

Another approach I have considered is adding the following code to the .htaccess file in the web root.

Redirect 301 /?page_id=123 https://www.exacmple.com/node/321


Again, I am unsure if this approach is recommended for Drupal 8.

How should I add redirects and avoid the new Drupal site is penalized in search results?
The warning you're seeing is generated by the Redirect module when you try to redirect from a path (the part without the query string) which is already a valid Drupal path, which is true for your case (your redirect's source path is the site root, /): https://git.drupalcode.org/project/redirect/-/blob/8.x-1.x/src/Plugin/Field/FieldWidget/RedirectSourceWidget.php#L68. The query string is ignored in this validation step.

Without a query parameter, this would "cover up" the existing path and make it inaccessible, which is why the warning exists. But since your redirect does specify a query, this isn't a problem - the redirect only happens if the query matches ?page_id=123.

The warning should be safe to ignore; your initial approach was likely correct.