The repository was not down; my router had two wgets
The router runs Entware on a USB stick, which is how it gets a package manager, a cron and a few binaries that the stock firmware doesn't have. One evening opkg update started saying this:
Downloading http://bin.entware.net/aarch64-k3.10/Packages.gz
Updated list of available packages in /opt/var/opkg-lists/entware
Downloading https://example.github.io/feed/all/Packages.gz
wget: not an http or ftp url: https://example.github.io/feed/all/Packages.gz
* opkg_download: Failed to download ... wget returned 1.
Two feeds, same command, same minute. The first one worked. The second is a small third-party feed I had added months ago, and it had been fine.
I did what everyone does: opened the URL in a browser (200), curled it from the router (200, 120 ms), checked DNS, checked the clock in case of a certificate date problem. Everything was healthy. The only broken thing in the whole chain was the sentence not an http or ftp url, which is not a network error at all. It is a parser saying it doesn't recognise the scheme.
Two binaries, one name
opkg doesn't download anything itself. It shells out to wget, and takes whichever one the PATH offers first. On this box there were two:
/opt/usr/bin/wget -> busybox
/opt/bin/wget -> /opt/libexec/wget-ssl
And the PATH was:
/opt/usr/sbin:/opt/usr/bin:/opt/sbin:/opt/bin:/usr/sbin:/usr/bin:/sbin:/bin
/opt/usr/bin comes first, so wget meant busybox. The busybox applet on this build is compiled without TLS. It parses http:// and ftp://, sees https://, and refuses the argument before touching the network — hence the wording. Plain-http feeds kept working, which is exactly why it looked like one repository was having a bad week rather than a local problem.
The fix, and the one-liner to prove it
PATH=/opt/bin:$PATH opkg update
That one line downloaded the feed that had been "unavailable" for weeks. The permanent version is the same idea in the init script that runs updates, putting the directory of the TLS-capable binary ahead of the busybox one.
The general shape of this bug is worth keeping in your head, because it has nothing to do with routers:
- A program that shells out to a helper inherits your environment, not a sane one. Cron, init scripts and web services each have a different PATH, so the same command can pick a different binary depending on who runs it.
- Embedded systems deliberately ship cut-down twins of common tools. The busybox applet is not a worse
wget; it is a different program with the same name and a tenth of the features. - An error message that names a syntax problem while you are debugging a network problem is a strong hint that you are looking at the wrong layer.
not an http or ftp urlnever meant the server was down.
The diagnostic that would have saved me the evening is two commands long:
which -a wget
wget --version | head -1
If the first prints two paths and the second says BusyBox, you already know the answer.