Problems with URL in a configuration for Ecto

I’m trying to use an URL configuration for a database connection in Ecto.

config :my_app, MyApp.Repo,
  adapter: Ecto.Adapters.Postgres,
  url: {:system, "DB_URL"},
  pool_size: 20

And then run an application with DB_URL=ecto://postgres:mypwdWith#Symbol/some_db
I get Ecto.InvalidURLError invalid url ..., path should be a database name error.

I checked source code and saw, that this URL string parses using url |> URI.decode() |> URI.parse()
I tried it and saw that after # symbol everything parses as a url fragment. I encoded this symbol to %23 and tried. But received the same result, because it decodes before parses.

Looks like I can’t use # symbol in a DB password, Am I missing something?

1 Like

Did you try escaping it with backslash?

1 Like

Thanks for the reply, but your suggestion doesn’t work.

1 Like

You can use # symbol in your database password, but if you’re using URL as your connection string, that character separates the URL itself from fragment id, see https://en.wikipedia.org/wiki/Fragment_identifier

edit: Sorry if the above is obvious, I’m not sure whether that’s a bug or feature :wink:

1 Like

Weird it is being decoded, but if it is only doing it once maybe you could double encode it? “%2523” for the “#”?

1 Like

I just had the same idea but I think it won’t work. Worth a shot. A long shot.

1 Like

I tried this also. It creates a valid URL to parse, but password is wrong.

1 Like

Decoding before we parse it is wrong. It is fixed in master, can you please give it a try? If it works I can backport it to 2.1.

3 Likes

It works now. Thanks for a super fast fix!
Next time I’ll make a PR instead of bother people on the forum :slight_smile:

2 Likes

Currently running ecto 2.2.8 and facing the same issue with a password ending in ‘#’.
Am I missing something?

Thanks in advance,

Mark

My issue was solved with the fix. So probably it’s something else.

I get the exact same error message.
Have removed the # from the password to get around the issue for the time being.