Repository: yt-dlp/yt-dlp
Issue category: Bug Report

Issue:
--update flag updates to the wrong software architecture
### DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE

- [X] I understand that I will be **blocked** if I *intentionally* remove or skip any mandatory\* field

### Checklist

- [X] I'm reporting a bug unrelated to a specific site
- [X] I've verified that I have **updated yt-dlp to nightly or master** ([update instructions](https://github.com/yt-dlp/yt-dlp#update-channels))
- [X] I've checked that all provided URLs are playable in a browser with the same IP and same login details
- [X] I've checked that all URLs and arguments with special characters are [properly quoted or escaped](https://github.com/yt-dlp/yt-dlp/wiki/FAQ#video-url-contains-an-ampersand--and-im-getting-some-strange-output-1-2839-or-v-is-not-recognized-as-an-internal-or-external-command)
- [X] I've searched [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates
- [X] I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue)

### Provide a description that is worded well enough to be understood

I was using `yt-dlp_linux_armv7l`, but using the `--update` flag updated me to the `yt-dlp_linux_aarch64` binary.

Attempting to run the updated binary doesn't work because it uses the wrong software architecture:
```
$ ./yt-dlp_linux_armv7l --help
bash: ./yt-dlp_linux_armv7l: No such file or directory
```

Steps to reproduce:

1. Download version `2024.12.06/yt-dlp_linux_armv7l` and confirm it is the right binary:
    1. `mkdir test ; cd test`
    2. `wget https://github.com/yt-dlp/yt-dlp/releases/download/2024.12.06/yt-dlp_linux_armv7l ; chmod a+x ./yt-dlp_linux_armv7l`
    3. `sha256sum ./yt-dlp_linux_armv7l`
    4. observer sha256 output `ed7ce4a5508dbecb5e0272ae57023eae243b4ac73d0969a498844fc3e111d8b4` is correct
    5. `file ./yt-dlp_linux_armv7l`
    6. Observe output is correct: `./yt-dlp_linux_armv7l: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, BuildID[sha1]=9a7fa40acc4aaeaf3d330fc2fc510872be2db480, for GNU/Linux 3.2.0, stripped`
 2. Update yt-dlp and observe it now uses the wrong architecture
     1. `./yt-dlp_linux_armv7l -vU` (verbose log pasted below)
     2. `sha256sum ./yt-dlp_linux_armv7l`
     3. observer sha256 output `d55bb8356ce48facdd0d1c34a54fc947824210a2bf67c9e2569b1b59080df7c1` corresponds to the linux_aarch64 architecture now rather than linux_armv7l
     4. `file ./yt-dlp_linux_armv7l`
     5. Observe output confirms we have the wrong architecture now: `./yt-dlp_linux_armv7l: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=165c3840e46a056d08c976cddc9073109cf26ee7, for GNU/Linux 3.7.0, stripped`

### Provide verbose output that clearly demonstrates the problem

- [X] Run **your** yt-dlp command with **-vU** flag added (`yt-dlp -vU <your command line>`)
- [X] If using API, add `'verbose': True` to `YoutubeDL` params instead
- [X] Copy the WHOLE output (starting with `[debug] Command-line config`) and insert it below

### Complete Verbose Output

```shell
[debug] Command-line config: ['-vU']
[debug] Encodings: locale UTF-8, fs utf-8, pref UTF-8, out utf-8, error utf-8, screen utf-8
[debug] yt-dlp version stable@2024.12.06 from yt-dlp/yt-dlp (linux_aarch64_exe)
[debug] Python 3.9.5 (CPython aarch64 32bit) - Linux-6.1.21-v8+-aarch64-with-glibc2.31 (OpenSSL 1.1.1f  31 Mar 2020, glibc 2.31)
[debug] exe versions: ffmpeg 4.3.8-0, ffprobe 4.3.8-0
[debug] Optional libraries: Cryptodome-3.21.0, brotli-1.1.0, certifi-2024.08.30, mutagen-1.47.0, requests-2.32.3, sqlite3-3.31.1, urllib3-2.2.3, websockets-14.1
[debug] Proxy map: {}
[debug] Request Handlers: urllib, requests, websockets
[debug] Loaded 1837 extractors
[debug] Fetching release info: https://api.github.com/repos/yt-dlp/yt-dlp/releases/latest
[debug] Downloading _update_spec from https://github.com/yt-dlp/yt-dlp/releases/latest/download/_update_spec
[debug] Downloading SHA2-256SUMS from https://github.com/yt-dlp/yt-dlp/releases/download/2024.12.13/SHA2-256SUMS
Current version: stable@2024.12.06 from yt-dlp/yt-dlp
Latest version: stable@2024.12.13 from yt-dlp/yt-dlp
Current Build Hash: ed7ce4a5508dbecb5e0272ae57023eae243b4ac73d0969a498844fc3e111d8b4
Updating to stable@2024.12.13 from yt-dlp/yt-dlp ...
[debug] Downloading yt-dlp_linux_aarch64 from https://github.com/yt-dlp/yt-dlp/releases/download/2024.12.13/yt-dlp_linux_aarch64
Updated yt-dlp to stable@2024.12.13 from yt-dlp/yt-dlp
```



Hints:
Is the verbose log you've provided the armv7l binary updating to the aarch64 binary?

If so, the armv7l binary is detecting itself as being the aarch64
>Is the verbose log you've provided the armv7l binary updating to the aarch64 binary?

Yes.

>If so, the armv7l binary is detecting itself as being the aarch64

Agreed -- very weird

Do you have python installed on your armv7l machine? If so, could you show the output of this command:
```
python -c "import platform; print(platform.machine())"
```
Here is the output you requested:
```
% python3 -c "import platform; print(platform.machine())"
aarch64
```

I'm using a raspberry pi 4b. I'm running 32 bit raspbian OS on it. 

The output of `uname -a` is misleading on the system -- the `aarch64` output makes it seem like it is a 64 bit OS:
```
% uname -a
Linux piwall 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr  3 17:24:16 BST 2023 aarch64 GNU/Linux
```

However, this output shows that it is actually a 32 bit OS:
```
% getconf LONG_BIT
32
```

In case it's helpful, here's some more output from my system:
```
% cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 11 (bullseye)"
NAME="Raspbian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
```
Thanks. Could you also show the output of this command please?
```
python3 -c "import sys; print(sys.maxsize > 2**32)"
```
Sure:
```
% python3 -c "import sys; print(sys.maxsize > 2**32)"
False
```
I think we could patch it like this:
```diff
diff --git a/yt_dlp/update.py b/yt_dlp/update.py
index ca2ec5f37..9ccd44b5e 100644
--- a/yt_dlp/update.py
+++ b/yt_dlp/update.py
@@ -65,9 +65,14 @@ def _get_variant_and_executable_path():
             machine = '_legacy' if version_tuple(platform.mac_ver()[0]) < (10, 15) else ''
         else:
             machine = f'_{platform.machine().lower()}'
+            is_64bits = sys.maxsize > 2**32
             # Ref: https://en.wikipedia.org/wiki/Uname#Examples
             if machine[1:] in ('x86', 'x86_64', 'amd64', 'i386', 'i686'):
-                machine = '_x86' if platform.architecture()[0][:2] == '32' else ''
+                machine = '_x86' if not is_64bits else ''
+            # platform.machine() on 32-bit raspbian OS may return 'aarch64', so check "64-bitness"
+            # See: https://github.com/yt-dlp/yt-dlp/issues/11813
+            elif machine[1:] == 'aarch64' and not is_64bits:
+                machine = '_armv7l'
             # sys.executable returns a /tmp/ path for staticx builds (linux_static)
             # Ref: https://staticx.readthedocs.io/en/latest/usage.html#run-time-information
             if static_exe_path := os.getenv('STATICX_PROG_PATH'):
```

@Grub4K what do you think?

Patch:
diff --git a/yt_dlp/update.py b/yt_dlp/update.py
index ca2ec5f376a0..9ccd44b5e77d 100644
--- a/yt_dlp/update.py
+++ b/yt_dlp/update.py
@@ -65,9 +65,14 @@ def _get_variant_and_executable_path():
             machine = '_legacy' if version_tuple(platform.mac_ver()[0]) < (10, 15) else ''
         else:
             machine = f'_{platform.machine().lower()}'
+            is_64bits = sys.maxsize > 2**32
             # Ref: https://en.wikipedia.org/wiki/Uname#Examples
             if machine[1:] in ('x86', 'x86_64', 'amd64', 'i386', 'i686'):
-                machine = '_x86' if platform.architecture()[0][:2] == '32' else ''
+                machine = '_x86' if not is_64bits else ''
+            # platform.machine() on 32-bit raspbian OS may return 'aarch64', so check "64-bitness"
+            # See: https://github.com/yt-dlp/yt-dlp/issues/11813
+            elif machine[1:] == 'aarch64' and not is_64bits:
+                machine = '_armv7l'
             # sys.executable returns a /tmp/ path for staticx builds (linux_static)
             # Ref: https://staticx.readthedocs.io/en/latest/usage.html#run-time-information
             if static_exe_path := os.getenv('STATICX_PROG_PATH'):


Test patch: