URI::InvalidURIError : The scheme mysql2 does not accept the registry part

How you can end up with the URI::InvalidURIError

This error is pretty easy to end up with if you have database URL with embedded username and password, although it’s also possible if you’re using basic auth over https.

Example problem URL

Suppose you have a URL such as mysql2://my-user-name:passwordwith.and#and$init@mymacbook.local:3306/db. The passwordwith.and#and$init will cause an error message:

URI::InvalidURIError (the scheme mysql2 does not accept registry part: my-user-name:passwordwith.and (or bad hostname?))

Solution

The above error message ends before the first problematic character (#). These need to be URL encoded (%23 for '#'). mysql2://my-user-name:passwordwith.Eand%23and$init@mymacbook.local:3306/db should pass.

Using Ruby to Quickly validate the URLs

The URI::RFC2396_Parser in ruby can provide a quicker way to validate vs. trying to boot an application dependent on the URL:

irb(main):013:0> URI::RFC2396_Parser.new.parse('mysql2://my-user-name:passwordwith%2Eand#a
nd$init@mymacbook.local:3306/db')
Traceback (most recent call last):
        8: from /Users/tpowell/.rbenv/versions/2.7.2/bin/irb:23:in `<main>'
        7: from /Users/tpowell/.rbenv/versions/2.7.2/bin/irb:23:in `load'
        6: from /Users/tpowell/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/irb-1.2.6/exe/irb:11:in `<top (required)>'
        5: from (irb):12
        4: from (irb):13:in `rescue in irb_binding'
        3: from /Users/tpowell/.rbenv/versions/2.7.2/lib/ruby/2.7.0/uri/rfc2396_parser.rb:219:in `parse'
        2: from /Users/tpowell/.rbenv/versions/2.7.2/lib/ruby/2.7.0/uri/rfc2396_parser.rb:219:in `new'
        1: from /Users/tpowell/.rbenv/versions/2.7.2/lib/ruby/2.7.0/uri/generic.rb:208:in `initialize'
URI::InvalidURIError (the scheme mysql2 does not accept registry part: my-user-name:passwordwith%2Eand (or bad hostname?))
irb(main):014:0> URI::RFC2396_Parser.new.parse('mysql2://my-user-name:passwordwith%2Eand%2
3and$init@mymacbook.local:3306/db')
=> #<URI::Generic mysql2://my-user-name:passwordwith%2Eand%23and$init@mymacbook.local:3306/db>