`initialize': the scheme postgres does not accept registry part: postgres:@ (or bad hostname?) (URI::InvalidURIError) with Docker

Rename your environment variable!

DATABASE_URL is reserved by Rails, and interpreted by ActiveRecord itself. I ran into the same issue.

Instead, use something like this:

    host:     <%= ENV['DB_HOST'] %>
    password: <%= ENV['DB_PWD'] %>

From the "Configuring Rails Applications" guide, it would appear that DATABASE_URL is used for configuring database access. Another way to configure database access is the presence of the file config/database.yml. Trying to use both methods to configure database access causes the issue you are facing.

if your password contains unsafe characters

Connection string used for DATABASE_URL cannot contain special characters (anything other than [a-zA-Z0-9_~-\.], e.g. @ is a common one to mess up). Solution is to url-encode.

if you are using dokku

  • https://github.com/Kloadut/dokku-pg-plugin/issues/76 - Host and Port information are missing
  • https://github.com/dokku/dokku-postgres/issues/28 - Rewritten link command generates invalid host

if you are using pghero

  • https://github.com/ankane/pghero - Fail to start if password contain @

The accepted answer is wrong. There's nothing wrong with using DATABASE_URL in your database.yml, although doing so explicitly is probably redundant. The problem is with the value of the URL.

ActiveRecord uses URI::RFC2396_Parser to parse database URLs. The error message above indicates that it's not able to parse the URL, probably because the hostname is missing, cf.

URI::RFC2396_Parser.new.parse('postgres://postgres:@/mydb')
# Traceback (most recent call last):
#       1: from (irb):30
# URI::InvalidURIError (the scheme postgres does not accept registry part: postgres:@ (or bad hostname?))

Other invalid hostnames, such as hostnames with underscores (common in docker-compose setups) will cause similar errors:

URI::RFC2396_Parser.new.parse('postgres://postgres:postgres@my_postgres/mydb')
# Traceback (most recent call last):
#        1: from (irb):34
# URI::InvalidURIError (the scheme postgres does not accept registry part: postgres:postgres@my_postgres (or bad hostname?))

What can be especially confusing is that URI.parse() uses URI::RFC3986_Parser, which is much more forgiving, and will accept either of these "bad" URLs.