The dark keyboard problem
You boot into Fedora after a fresh install or a major update. The desktop loads, your Wi-Fi connects, but the keyboard is completely dark. You tap the function keys. Nothing happens. You open the settings menu and find the brightness slider grayed out or stuck at zero. This happens on almost every laptop brand at least once. The kernel simply has not loaded the correct driver to talk to the backlight controller, or the brightness value is sitting at zero from a previous session.
What the kernel is actually doing
Linux exposes hardware controls through the sysfs virtual filesystem. The backlight controller lives under /sys/class/backlight/. Each directory inside that path represents a hardware interface. Inside each directory you will find files like brightness, max_brightness, and actual_brightness. Writing a number to brightness tells the kernel to adjust the PWM signal or voltage to the LED strip. The kernel module that owns that directory is usually acpi_backlight, but modern laptops often use vendor-specific modules like intel_backlight, amdgpu_bl, or thinkpad_acpi. If the wrong module loads first, it grabs the sysfs path and leaves the backlight unresponsive. The kernel also remembers the last brightness value. If it was zero when you shut down, it stays zero on boot.
Check the available interfaces before guessing which driver to load.
ls /sys/class/backlight/
# Lists every backlight controller the kernel currently recognizes
# Output usually shows acpi_video0, intel_backlight, or amdgpu_bl0
# Pick the directory that matches your hardware vendor
Run ls /sys/class/backlight/ first. Pick the right directory before writing to it.
Load the driver and set the brightness
The acpi_backlight module handles generic ACPI backlight controls. Many laptops need it explicitly loaded because newer kernels prefer vendor-specific drivers by default. Loading it manually forces the kernel to expose the ACPI interface. Once the interface exists, writing to the brightness file applies the change immediately.
sudo modprobe acpi_backlight
# Loads the generic ACPI backlight driver into the running kernel
# This creates the acpi_video0 sysfs interface if it was missing
# The module stays loaded until you reboot or explicitly remove it
sudo sh -c 'echo 255 > /sys/class/backlight/acpi_video0/brightness'
# Uses a subshell with root privileges to write to a protected sysfs file
# 255 is the maximum value for most ACPI backlight controllers
# Redirecting to brightness triggers the kernel to update the hardware
If your laptop uses a different controller, swap acpi_video0 with the directory name you found earlier. The max_brightness file inside that directory tells you the upper limit. Some AMD systems cap at 10. Some Intel systems cap at 255. Write the exact maximum to avoid clamping errors.
cat /sys/class/backlight/acpi_video0/max_brightness
# Reads the hardware limit without modifying anything
# Use this number instead of guessing 255
# Prevents kernel warnings about out-of-range values
Load the module and write the value. The keyboard should light up within a second.
Make the change survive a reboot
Manual modprobe commands vanish when you restart. The kernel only loads modules that are listed in the initramfs or explicitly configured in /etc/modprobe.d/. You need a persistent configuration file so the driver loads automatically on every boot. Fedora follows the standard Linux convention: user modifications go in /etc/, while package defaults live in /usr/lib/. Never edit files in /usr/lib/. They get overwritten during updates.
Create a small configuration file that tells modprobe to load the backlight driver early.
echo "install acpi_backlight /bin/true" | sudo tee /etc/modprobe.d/acpi_backlight.conf
# This specific line actually blocks the module. Do not use it.
# The correct approach is to whitelist the module in dracut
# See the next block for the proper persistent method
The correct persistent method uses dracut to bake the module into the initramfs. This ensures the kernel loads it before the root filesystem mounts.
echo "acpi_backlight" | sudo tee /etc/modules-load.d/acpi_backlight.conf
# Creates a persistent module load list in the standard systemd path
# systemd-modules-load.service reads this file during early boot
# The module loads automatically without manual intervention
sudo dracut --force
# Rebuilds the initramfs with the new module configuration
# --force overwrites the existing image safely
# Required for changes to take effect on next boot
Reboot before you debug. Half the time the symptom is gone.
Verify the backlight responds
Verification requires checking both the sysfs value and the kernel logs. The actual_brightness file shows what the hardware is currently doing. The journal shows whether the module loaded cleanly or hit a firmware warning.
cat /sys/class/backlight/acpi_video0/actual_brightness
# Confirms the kernel successfully wrote the value to hardware
# Should match the number you wrote to brightness
# A mismatch means the driver failed to communicate with the EC
journalctl -xeu systemd-modules-load.service
# Shows early boot logs with explanatory text and jumps to the end
# Confirms the module loaded without dependency errors
# Use -xeu to filter only the relevant unit output
If actual_brightness returns zero but you wrote a higher number, the embedded controller is rejecting the command. Check the next section for firmware conflicts.
Read the actual error before guessing.
Common pitfalls and exact error strings
Three problems dominate this issue. The first is a permission error when writing to sysfs. The second is a missing directory because the wrong driver grabbed the interface. The third is a function key conflict where GNOME or KDE intercepts the brightness keys.
The permission error looks exactly like this:
bash: /sys/class/backlight/acpi_video0/brightness: Permission denied
The shell cannot write to sysfs as a normal user. The sudo sh -c wrapper in the earlier command solves this. Do not use sudo echo. The redirection happens in the unprivileged shell before sudo runs.
The missing directory error appears when you run ls /sys/class/backlight/ and see intel_backlight instead of acpi_video0. The Intel driver claims the hardware and hides the ACPI interface. You have two choices. You can blacklist the Intel driver and force the ACPI one, or you can write to the Intel path instead.
echo "blacklist intel_backlight" | sudo tee /etc/modprobe.d/disable_intel_bl.conf
# Prevents the vendor driver from claiming the backlight controller
# Forces the kernel to fall back to the generic ACPI interface
# Rebuild initramfs after creating this file
The function key conflict shows up in the desktop environment logs. GNOME reads the brightness value from the same sysfs path. If the path changes or the module loads late, the settings panel shows a grayed slider. Restarting the desktop shell or logging out and back in usually syncs the UI with the kernel state.
loginctl terminate-user $USER
# Kills all user sessions and forces a clean re-login
# Clears stale desktop environment caches
# Safer than manually restarting GNOME Shell in Wayland
Trust the package manager. Manual file edits drift, snapshots stay.
When to use this approach versus alternatives
Use modprobe acpi_backlight when your laptop uses a generic ACPI interface and the driver failed to load automatically. Use blacklist intel_backlight when the Intel driver claims the hardware but leaves the backlight unresponsive. Use amdgpu_bl configuration when you are on a modern AMD laptop and the brightness slider does nothing. Use thinkpad_acpi when you are on a Lenovo machine and the function keys control the fan instead of the LEDs. Stay on the default desktop environment brightness slider if the sysfs path exists and the kernel module is already loaded.
Run journalctl -xe first. Read the actual error before guessing.