How to Install SA-MP Plugins on Linux: A Practical Guide for VPS
Technical tutorial to install SA-MP plugins on a Linux VPS: download the correct 32-bit .so, configure server.cfg, resolve glibc dependencies, and fix common errors.
Plugins are what make SA-MP usable in production: streamer (for large maps without object limits), mysql (persistence), sscanf (command parsing), among others. On Linux the installation is more sensitive than on Windows, mainly because of the server’s 32-bit architecture — downloading a 64-bit .so is the most common cause of “plugin won’t load” on freshly provisioned VPS.
This tutorial covers the full flow: download the correct plugin, place it in the right directory, declare it in server.cfg, resolve glibc dependencies, and validate the load through the logs. The target reader is a SA-MP server owner migrating from a managed host to a Linux VPS who needs to understand why commands that “always worked” on Windows silently break on Linux.
Estimated time: 15 to 20 minutes per plugin, including download and validation. For a server with 4 to 6 plugins, expect about an hour of initial configuration.
Prerequisites
Linux VPS with SA-MP server 0.3.7-R2 already installed and running (without plugins). sudo access to install 32-bit packages. Basic knowledge of SSH and editing files with nano or vim.
Before starting, confirm the reference points of your server. You will need these values throughout the tutorial:
i386 (32-bit) plugins/ server.cfg server_log.txt Make sure you are inside the SA-MP server directory:
cd ~/samp03
ls -la samp03svr
The output should show the samp03svr binary with execute permission. If you installed it in a different path, adjust the tutorial commands accordingly. Also confirm the binary architecture:
file samp03svr
The expected output contains ELF 32-bit LSB executable, Intel 80386. This confirms you need 32-bit plugins — regardless of whether the VPS runs a 64-bit kernel.
Install 32-bit dependencies on the system
Most modern VPS kernels are 64-bit, but the SA-MP server is compiled for 32-bit. For the binary and plugins to find their libraries, you need to install the i386 variants of glibc and libstdc++.
Enable the i386 architecture in dpkg (required on 64-bit Debian/Ubuntu):
sudo dpkg --add-architecture i386
sudo apt updateThis makes the package manager recognize 32-bit packages as installable on the system. Without this step, apt rejects packages with the :i386 suffix saying they are unavailable.
Install the libraries that the SA-MP server and most plugins need:
sudo apt install -y libc6:i386 libstdc++6:i386 lib32gcc-s1 zlib1g:i386libc6 is the 32-bit glibc — the base for everything. libstdc++6 is required for plugins compiled in C++ (the vast majority). lib32gcc-s1 brings the 32-bit GCC runtime. zlib1g appears as an indirect dependency in plugins that compress data.
If you plan to use the MySQL R39+ plugin, also install libmariadb-dev-compat:i386 or libmysqlclient21:i386. Without it, the plugin loads but fails on any query with Could not load libmariadb.
Download the correct plugin
This is the step where most errors happen. Plugins ship separate releases for Windows (.dll) and Linux (.so), and inside Linux there is still the 32 vs 64-bit split. Picking the wrong one returns Failed. in the log with no clear explanation.
Identify the official plugin repository. The most common ones:
- streamer — github.com/samp-incognito/samp-streamer-plugin
- sscanf — github.com/Y-Less/sscanf
- mysql (R41) — github.com/pBlueG/SA-MP-MySQL
- fixes2 — github.com/Y-Less/samp-plugin-fixes2
Open Releases and look for the Linux file. The name varies: streamer-2.9.6-linux.zip, sscanf.so, mysql-R41-4-linux-static.tar.gz.
Download it straight to the server with wget. Example for streamer:
cd /tmp
wget https://github.com/samp-incognito/samp-streamer-plugin/releases/download/v2.9.6/samp-streamer-plugin-2.9.6-linux.zip
unzip samp-streamer-plugin-2.9.6-linux.zipInside the .zip there is typically plugins/streamer.so (32-bit) and/or plugins/streamer.x64.so. Always use the one without the .x64 suffix.
Validate the .so architecture before copying it to the server:
file plugins/streamer.soThe output must contain ELF 32-bit LSB shared object, Intel 80386. If it shows x86-64, you downloaded the wrong file — go back to the release and pick the other one.
Pre-compiled plugins from forums or Discord can contain backdoors (there are documented cases in the SA-MP community). Always use the official release from the author’s GitHub repository. If you need to modify it, build it yourself from source.
Move the plugin and adjust permissions
The SA-MP loader looks for .so files in a single path: the plugins/ directory next to the binary. There is no configuration to change this.
Create the plugins/ directory if it does not exist yet and copy the .so:
cd ~/samp03
mkdir -p plugins
cp /tmp/plugins/streamer.so plugins/Repeat for every plugin you downloaded. Keep the original filename — we will reference it in server.cfg without the .so extension.
Adjust permissions. The file must be readable and executable by the user running the server:
chmod 644 plugins/*.soPermissions 755 also work but are not necessary — the .so is loaded through dlopen, not executed directly. On shared servers, avoid 777 on principle.
Register plugins in server.cfg
The server.cfg controls which plugins the server tries to load at startup. The plugins line accepts names separated by spaces, in the desired order.
Open server.cfg in your editor:
nano server.cfgLook for the plugins line (it may not exist yet). If it isn’t there, add it at the top of the file. The format is a single line:
plugins streamer sscanf mysqlNote: no .so, no path, separated by spaces. The loader appends .so automatically and searches in plugins/.
Save (Ctrl+O in nano, Enter, Ctrl+X) and double-check the line. Typos here produce Failed. in the log with the corrupted name — streame instead of streamer.
When a plugin depends on another, declare the dependent after. mysql before any plugin that runs queries at startup; streamer before scripts that register dynamic items via callbacks. When in doubt, read the plugin README — authors document required ordering.
Verification
With everything in place, start the server and read the log to confirm each plugin loaded.
Start the server in the foreground to watch the output in real time:
./samp03svrIn the first few seconds, the server enumerates the plugins. You should see something like:
Loading plugin: streamer.so
*** Streamer Plugin v2.9.6 by Incognito loaded ***
Loaded.
Loading plugin: sscanf.so
===============================
sscanf plugin loaded.
Version: 2.8.3
(c) 2022 Alex "Y_Less" Cole
===============================
Loaded.Each plugin ends with Loaded. on its own line. If Failed. appears, the error message is on the line immediately above — take note of the exact error.
Stop the server (Ctrl+C) and inspect server_log.txt:
grep -E "Loaded\.|Failed\." server_log.txt | tail -20You should see one Loaded. line for each plugin declared in server.cfg. If the Loaded. count is lower than expected, some plugin failed to load.
Troubleshooting
”Failed (libplugin.so: wrong ELF class: ELFCLASS64)”
You downloaded the 64-bit version of the plugin. Go back to the GitHub release and pick the file without the .x64 suffix. Confirm with file plugins/yourplugin.so before trying again — it must show Intel 80386, not x86-64.
”Failed (libplugin.so: cannot open shared object file)”
The .so file is not in plugins/ or has a different name from the one declared in server.cfg. List the directory with ls plugins/ and compare against the plugins line in the config. Names are case-sensitive on Linux — MySQL.so is not the same as mysql.so.
”Failed (libstdc++.so.6: cannot open shared object file)”
The 32-bit libs are missing from the system. Go back to the “Install 32-bit dependencies” section and confirm libstdc++6:i386 is installed:
dpkg -l | grep libstdc++6:i386
If it does not show up, install it and restart the server.
Plugin loads but crashes at runtime
Use ldd to identify unsatisfied dependencies that dlopen accepts but fail later:
ldd plugins/yourplugin.so
Lines with not found indicate missing libs. For MySQL plugins it is usually libmariadb or libmysqlclient. Install the matching :i386 version.
Next steps
With plugins loading correctly, the natural next step is to configure automatic startup through systemd so the server survives VPS reboots. After that, configuring backups for the database (if you use the MySQL plugin) and for the scriptfiles/ directory is what separates a hobby setup from a production one.
If you are migrating to a dedicated VPS, it is worth reviewing kernel limits — a low ulimit -n drops the server when player count grows. The default of 1024 file descriptors handles servers up to ~500 slots; above that, raise it to 4096+ in /etc/security/limits.conf.
For production servers, a Hostini VPS optimized for games ships with a kernel tuned for low latency, protection against UDP flood attacks (common against SA-MP ports), and NVMe storage — relevant when the server does heavy I/O on scriptfiles/. The 32-bit libraries also come pre-installed on Linux images for SA-MP, saving the first steps of this tutorial.
Frequently asked questions
Why does the .so plugin throw 'wrong ELF class' when the server starts?
The SA-MP server binary is 32-bit (i386) and only loads plugins compiled for 32-bit. This error appears when you download the x86_64 build (a 64-bit .so). Always pick the file labeled `Linux` or `i386` in the plugin release — not `Linux x64`. In some repositories the plain `.so` is the 32-bit build, while `.x64.so` is the 64-bit one.
Do I need to install lib32 packages even on a headless server?
Yes. The SA-MP server and its plugins call dlopen against 32-bit glibc and dependencies like libstdc++. Without `libc6:i386`, `libstdc++6:i386`, and `lib32gcc-s1`, the server fails silently or gets stuck in a reconnection loop. Install the 32-bit packages even if your VPS runs a 64-bit kernel.
Can I drop the plugin in the server root instead of plugins/?
No. The SA-MP loader only looks for files in `plugins/` relative to the server binary. Putting them anywhere else returns `Failed (libpluginxyz.so: cannot open shared object file)`. Create the directory if it does not exist and keep files at permission 644.
Does the plugin order in server.cfg matter?
Yes, when there are mutual dependencies. Plugins like `mysql` must come before wrappers that depend on them, and `streamer` before scripts that register streaming callbacks at startup. When in doubt, read the plugin README: most authors document required ordering explicitly.
How do I know whether the plugin really loaded?
Check `server_log.txt` right after startup. Each plugin prints a line like `Loaded.` or `Loading plugin: pluginname.so`. If you see `Failed.`, the reason is on the line above — usually wrong architecture or a missing dependency. Run `ldd plugins/yourplugin.so` to find libs marked `not found`.
Do I need to restart the server every time I add a plugin?
Yes. The SA-MP server only loads plugins at startup — there is no hot-reload. Stop the process (Ctrl+C or `systemctl stop`), edit `server.cfg`, place the file inside `plugins/`, and start the server again. Changes to a `.so` at runtime have no effect until the next startup.