marinakr

marinakr

NervesHubLink + Shared Secret on NervesCloud: WS upgrade 401 (TLS OK) on fresh app (RPi 5)

Context

I’m following the official tutorial to bring up a minimal Nerves app and connect it to NervesCloud using Shared Secret auth (no Phoenix, no extras). The device boots fine and has network, but the NervesHubLink fails the WebSocket upgrade with 401 even though TLS handshake succeeds.

Environment

  • Device: Raspberry Pi 5 (target rpi5)
  • Nerves: 1.11.3
  • nerves_hub_link: 2.7.3
  • VintageNet: 0.13.7
  • Host CLI:
    • nh config set uri "https://manage.nervescloud.com/"
    • nh user auth
    • Org: ***, Product: my_pi (empty list of devices so far)

What I did (repro)

  1. New project per tutorial (minimal app, no Phoenix).
  2. target.exs:
config :nerves_hub_link,
  host: "devices.nervescloud.com",
  remote_iex: true,
  shared_secret: [
    product_key: "NHP_...REDACTED...",     # freshly rotated in UI
    product_secret: "...REDACTED..."
  ]
  1. Built for MIX_TARGET=rpi5, burned, booted.
  2. SSH device console:
Nerves.Runtime.serial_number()
"9e5**********" # <- non-empty

:application.get_all_env(:nerves_hub_link)
[
  host: "devices.nervescloud.com",
  shared_secret: [
    product_key: "nhp_............******....",
    product_secret: "............******...."
  ],
  remote_iex: true,
  fwup_public_keys: []
]

iex(8)> :ssl.connect('devices.nervescloud.com', 443,
...(8)>   [verify: :verify_peer, cacerts: :public_key.cacerts_get()], 5000)
{:ok,
 {:sslsocket, {:gen_tcp, #Port<0.196>, :tls_connection, :undefined},
  [#PID<0.1633.0>, #PID<0.1632.0>]}}

Application.get_env(:nerves_hub_link, :host)
"devices.nervescloud.com"

Error reapeted:

[NervesHubLink] error: {:error, {:upgrade_failure,
  %{reason: %Mint.WebSocket.UpgradeFailureError{
      status_code: 401,
      headers: [
        {"date","Thu, 14 Aug 2025 14:11:08 GMT"},
        {"content-length","0"},
        {"cache-control","max-age=0, private, must-revalidate"}]},
    status_code: 401}}}

:alarm_handler: {:set, {NervesHubLink.Disconnected, [...]}}

I did setup secret keys few times, it is valid

The issue is in something else, I cant figure out it what
Does anyone have a clue what it can be?

Most Liked

joshknz

joshknz

Hey Marina

Thank you for sharing the full device serial number.

I’ve found error messages in our logs which confirm the case of a device with that id already existing in our system (device identifiers are unique across the platform).

I’ve also checked our DB and see that a device with that identifier is associated with a product and org. Could you DM me the name of the Org and Product the device was previously connected to?

Thanks

Josh

joshknz

joshknz

Thanks for the extra info @marinakr

I think the core of the issue is that Devices are initially soft deleted (recoverable) but need to be ‘destroyed’ after soft deleted.

Or you need to ‘move’ devices from one Product to another, which can be done on the Device list page.

None the less, this is an improvement we need to make on our end.

I’ll get the stuck devices removed ready for you to try again in the morning.

Where Next?

Popular in Questions Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a &gt; b) do {:ok, "a"} end if (a &lt; b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
dotdotdotPaul
Okay, I’m having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I’m sure I’...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

Other popular topics Top

malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement