Seems Erlang can not find cacerticate on android+termux

I am trying to run the following command on android+termux:

mix archive.install hex phx_new

But I got this error:

** (EXIT from #PID<0.95.0>) an exception was raised:
    ** (CaseClauseError) no case clause matching: :undefined
        (public_key 1.16.1) pubkey_os_cacerts.erl:40: :pubkey_os_cacerts.get/0
        (mix 1.17.2) lib/mix/utils.ex:664: Mix.Utils.read_httpc/1
        (mix 1.17.2) lib/mix/utils.ex:576: anonymous fn/2 in Mix.Utils.read_path/2
        (elixir 1.17.2) lib/task/supervised.ex:101: Task.Supervised.invoke_mfa/2
        (elixir 1.17.2) lib/task/supervised.ex:36: Task.Supervised.reply/4


15:29:42.543 [error] Task #PID<0.111.0> started from #PID<0.95.0> terminating
** (CaseClauseError) no case clause matching: :undefined
    (public_key 1.16.1) pubkey_os_cacerts.erl:40: :pubkey_os_cacerts.get/0
    (mix 1.17.2) lib/mix/utils.ex:664: Mix.Utils.read_httpc/1
    (mix 1.17.2) lib/mix/utils.ex:576: anonymous fn/2 in Mix.Utils.read_path/2
    (elixir 1.17.2) lib/task/supervised.ex:101: Task.Supervised.invoke_mfa/2
    (elixir 1.17.2) lib/task/supervised.ex:36: Task.Supervised.reply/4
Function: #Function<5.19587555/0 in Mix.Utils.read_path/2>
    Args: []

I opened an issue at termux package repo And someone suggested this fix 1 2. So I put the following in an elixir script:

cat fix.exs

:pub_key_os_cacerts.load(/data/data/com.termux/files/usr/etc/tls/cert.pem)

And ran the script elixir fix.exs then mix archive.install hex phx_new ran with no error.

The build script for erlang on android+termux can be found here

Does someone know what’s going?

1 Like

You a hit a bug that was fixed here.

Specifically, and in your case, you seem to have a non-standard path for certificates. If certificate bundles for any of the standard paths tied to your operating system (as defined in pubkey_os_cacerts) were not found, undefined was returned. However, the entry point function get/0 didn’t have a match clause for undefined, only for ok or an error tuple.

Your work-around succeeds because you load certs prior to get/0 being called somewhere such that you never end up in the clause via a call to get/0.