Fedora

Install Polybar Status Bar on Fedora 45 / 44 with i3

Polybar replaces the bar of an X11 tiling window manager with one you build from modules: workspaces, the focused window title, CPU, memory, disk, volume, network, a clock and a tray. Fedora packages it, so the old routine of cloning the source and running a build script is gone. What has changed on Fedora is the desktop underneath. Workstation’s GNOME session is Wayland only, and Polybar draws through X11. This guide pairs it with i3 instead, writes a config that survives both current releases, and starts one bar per monitor from i3. The steps were run on Fedora 45 and Fedora 44 in October 2026 with Polybar 3.7.2 and i3 4.25.1.

Original content from computingforgeeks.com - post 20781

Check that you are on an X11 session

Polybar needs an X server to draw on. Since Fedora 43, Workstation ships GNOME as Wayland only, with the X11 session packages removed. So the stock Workstation desktop is the wrong host. Use one of these:

  • The Fedora i3 Spin, which already runs i3 on X11.
  • A minimal or Server install of Fedora 45 or 44 with the i3 package group added, as below. That is what we tested. On Workstation, GDM stays the active login manager after the group install.
  • Another X11 window manager such as bspwm or Openbox. The Polybar part of this guide still applies; only the i3 wiring changes.

On Sway or another Wayland compositor, use Waybar instead. Our Sway and Waybar setup on Fedora covers that path. Once Polybar is installed, you can see the dependency for yourself: started without an X display, it stops at once:

env -u DISPLAY polybar main

The error names the missing display:

polybar|error: Uncaught exception, shutting down: X connection error... (what: Can't parse display string)

Install i3 and Polybar

Skip this group install on the i3 Spin. Elsewhere, add i3 with the Xorg server, the LightDM login screen, i3status, dmenu, the Xfce terminal and feh:

sudo dnf install @i3
sudo systemctl set-default graphical.target

On a minimal base this is the big step: 478 packages and 467 MiB of downloads on Fedora 45, 486 packages on Fedora 44, about 1 GiB installed on both. Reboot, choose the i3 session at the LightDM login screen, and log in. i3 starts with its own i3bar at the bottom.

Polybar comes from the main Fedora repository:

sudo dnf install polybar

It is a small package with two extra libraries:

Updating and loading repositories:
Repositories loaded.
Package       Arch   Version         Repository      Size
Installing:
 polybar      x86_64 0:3.7.2-10.fc45 fedora       2.8 MiB
Installing dependencies:
 jsoncpp      x86_64 0:1.9.6-3.fc44  fedora     285.6 KiB
 libmpdclient x86_64 0:2.26-2.fc45   fedora     193.4 KiB

Transaction Summary:
 Installing:         3 packages

Total size of inbound packages is 1 MiB. Need to download 1 MiB.
After this operation, 3 MiB extra will be used (install 3 MiB, remove 0 B).
[1/3] jsoncpp-0:1.9.6-3.fc44.x86_64     100% | 491.2 KiB/s | 110.0 KiB |  00m00s
[2/3] libmpdclient-0:2.26-2.fc45.x86_64 100% | 297.5 KiB/s |  72.0 KiB |  00m00s
[3/3] polybar-0:3.7.2-10.fc45.x86_64    100% |   2.3 MiB/s | 927.7 KiB |  00m00s
--------------------------------------------------------------------------------
[3/3] Total                             100% | 559.6 KiB/s |   1.1 MiB |  00m02s
Running transaction
[1/5] Verify package files              100% | 600.0   B/s |   3.0   B |  00m00s
[2/5] Prepare transaction               100% |  33.0   B/s |   3.0   B |  00m00s
[3/5] Installing libmpdclient-0:2.26-2. 100% |  31.8 MiB/s | 195.2 KiB |  00m00s
[4/5] Installing jsoncpp-0:1.9.6-3.fc44 100% |  70.1 MiB/s | 287.1 KiB |  00m00s
[5/5] Installing polybar-0:3.7.2-10.fc4 100% |  15.9 MiB/s |   2.8 MiB |  00m00s
Complete!

Check the build and the features compiled in:

polybar --version

Fedora 45 and Fedora 44 ship the same release with i3, PulseAudio and network support enabled:

polybar 3.7.2

Features: +alsa +curl +i3 +mpd +network(libnl) +pulseaudio +xkeyboard

The package installs two binaries, polybar and polybar-msg, plus a sample config at /etc/polybar/config.ini. That sample is identical to the upstream example config.

Install fonts that work on both releases

The bar needs a text font and an icon font. JetBrains Mono and Font Awesome are both packaged:

sudo dnf install fontawesome-fonts-all jetbrains-mono-fonts-all

This catches people out: the two releases ship different Font Awesome generations, and the family name carries the major version. Fedora 45 has Font Awesome 7. Fedora 44 has Font Awesome 6. A config that names one of them breaks on the other. Ask fontconfig what a Font Awesome 6 name resolves to on Fedora 45:

fc-match 'Font Awesome 6 Free:style=Solid'

It silently falls back to a text font, so every icon on the bar turns into an empty box:

NotoSans[wght].ttf: "Noto Sans" "Regular"

The fix is a fontconfig family list. Name both generations, newest first:

fc-match 'Font Awesome 7 Free,Font Awesome 6 Free:style=Solid'

Fedora 45 picks version 7:

Font Awesome 7 Free-Solid-900.otf: "Font Awesome 7 Free" "Solid"

Fedora 44 picks version 6 from the same string:

Font Awesome 6 Free-Solid-900.otf: "Font Awesome 6 Free" "Solid"

The config below uses that list, so one file works on both releases and keeps working after an upgrade.

Run the sample config once

Polybar reads ~/.config/polybar/config.ini and falls back to /etc/polybar/config.ini when that file does not exist. Before editing anything, list the outputs Polybar can see:

polybar --list-monitors

Our lab VM has one display:

Virtual-1: 1280x800+0+0 (primary)

The sample config defines one bar, called example. Start it for a few seconds to read the log:

timeout 6 polybar example

We ran this one over SSH with only DISPLAY set, which explains the first error. The rest are what a fresh install shows:

polybar|notice:  Parsing config file: /etc/polybar/config.ini
polybar|notice:  Listening for IPC messages (PID: 1333)
polybar|notice:  Loading module 'xworkspaces' of type 'internal/xworkspaces'
polybar|notice:  Loading module 'xwindow' of type 'internal/xwindow'
polybar|notice:  Loading module 'filesystem' of type 'internal/fs'
polybar|notice:  Loading module 'pulseaudio' of type 'internal/pulseaudio'
polybar|error: Disabling module "pulseaudio" (reason: Could not connect pulseaudio context.)
polybar|notice:  Loading module 'xkeyboard' of type 'internal/xkeyboard'
polybar|notice:  Loading module 'memory' of type 'internal/memory'
polybar|notice:  Loading module 'cpu' of type 'internal/cpu'
polybar|notice:  Loading module 'wlan' of type 'internal/network'
polybar|error: Disabling module "wlan" (reason: No interface found for type 'wireless')
polybar|notice:  Loading module 'eth' of type 'internal/network'
polybar|notice:  module/eth: Discovered wired interface eth0
polybar|notice:  Loading module 'date' of type 'internal/date'
polybar|notice:  Loaded 8 modules
polybar|notice:  Loaded font "monospace" (name=DejaVu Sans Mono, offset=2, file=/usr/share/fonts/dejavu-sans-mono-fonts/DejaVuSansMono.ttf)
polybar|warn:  background_manager: Failed to get root pixmap, default to black (is there a wallpaper?)
polybar|warn:  background_manager: Failed to get root pixmap, default to black (is there a wallpaper?)
polybar|warn:  background_manager: Failed to get root pixmap, default to black (is there a wallpaper?)
polybar|warn:  background_manager: Failed to get root pixmap, default to black (is there a wallpaper?)
polybar|notice:  Received signal(15): Terminated
polybar|notice:  Termination signal received, shutting down...

Each of those lines is covered in the error section at the end. None of them stops the bar.

Build your own config from the sample

Copy the sample into your home directory. From here on, Polybar ignores the file in /etc:

mkdir -p ~/.config/polybar && cp /etc/polybar/config.ini ~/.config/polybar/

Rename the bar to main, and let the launch script choose the monitor through an environment variable. An empty MONITOR means the primary output:

sed -i 's|^\[bar/example\]|[bar/main]|' ~/.config/polybar/config.ini
sed -i '/^\[bar\/main\]/a monitor = ${env:MONITOR:}' ~/.config/polybar/config.ini

Replace the single monospace font with JetBrains Mono for text and the Font Awesome list for icons. The ;2 suffix moves the glyphs down two pixels so they sit centred in the bar:

sed -i 's|^font-0 = .*|font-0 = "JetBrains Mono:size=10;2"\nfont-1 = "Font Awesome 7 Free,Font Awesome 6 Free:style=Solid:size=10;2"|' ~/.config/polybar/config.ini

Pick the right-hand modules. This drops the keyboard layout indicator and adds the system tray, which the sample defines but does not show:

sed -i 's|^modules-right = .*|modules-right = filesystem pulseaudio memory cpu wlan eth date systray|' ~/.config/polybar/config.ini

Swap the VOL, RAM and CPU text labels for icons. Font Awesome glyphs live in the Unicode private use area, and they tend to vanish when copied from a web page. The command writes them as UTF-8 byte escapes instead, which GNU sed turns into the real characters:

sed -i 's|"VOL "|"\xef\x80\xa8 "|; s|"RAM "|"\xef\x94\xb8 "|; s|"CPU "|"\xef\x8b\x9b "|' ~/.config/polybar/config.ini

The three escapes are the volume, memory and microchip icons. Finally, the wired network module prints your local IP address by default. Show traffic instead, which is more useful at a glance and keeps the address out of screenshots on a wired machine:

sed -i '/^\[module\/eth\]/,/^\[/ s|%local_ip%|%downspeed:8% %upspeed:8%|' ~/.config/polybar/config.ini

Review the bar section after the edits:

grep -nE '^\[bar/main\]|^monitor|^font-|^modules-' ~/.config/polybar/config.ini

The line numbers match the sample, with the two inserted lines:

28:[bar/main]
29:monitor = ${env:MONITOR:}
52:font-0 = "JetBrains Mono:size=10;2"
53:font-1 = "Font Awesome 7 Free,Font Awesome 6 Free:style=Solid:size=10;2"
55:modules-left = xworkspaces xwindow
56:modules-right = filesystem pulseaudio memory cpu wlan eth date systray

Every other module and colour comes from the sample. The Polybar wiki documents each module type and its settings when you want to go further.

Write a launch script

i3 should start the bar through a script, so a reload never stacks a second bar on top of the first. Create it:

nano ~/.config/polybar/launch.sh

Add this content:

#!/usr/bin/env bash
# Stop running bars, then start one bar per connected monitor
polybar-msg cmd quit >/dev/null 2>&1
while pgrep -u "$UID" -x polybar >/dev/null; do sleep 0.2; done

for m in $(polybar --list-monitors | cut -d: -f1); do
  MONITOR=$m polybar --reload main 2>&1 | tee -a "${XDG_RUNTIME_DIR:-/tmp}/polybar-$m.log" & disown
done

It asks any running bar to quit over IPC, waits for it to exit, then starts one main bar per monitor reported by --list-monitors. --reload restarts the bar whenever you save config.ini. Each monitor gets its own log under /run/user/. Make it executable:

chmod +x ~/.config/polybar/launch.sh

Start Polybar from i3

i3 reads ~/.config/i3/config. On the first login, i3-config-wizard offers to write that file. If you dismissed it, copy the system config there first:

mkdir -p ~/.config/i3 && cp /etc/i3/config ~/.config/i3/

Comment out the whole bar { } block so i3bar stops starting, then append the launcher:

sed -i '/^bar {/,/^}/ s/^/# /' ~/.config/i3/config
echo 'exec_always --no-startup-id $HOME/.config/polybar/launch.sh' >> ~/.config/i3/config

exec_always runs on every i3 restart, not just at login, which is what lets a restart pick up bar changes. The sample config turns on pseudo-transparency, and without a wallpaper Polybar logs “Failed to get root pixmap” four times on every start. feh came in with the i3 group and reads Fedora’s JPEG XL backgrounds. Set one once, which also writes ~/.fehbg:

feh --bg-fill /usr/share/backgrounds/default.jxl

Then restore the wallpaper on every start, by inserting that line above the Polybar launcher. i3 starts the two commands in order but does not wait for the first, so at login the bar can occasionally win the race and log the warning once; polybar-msg cmd restart clears it:

sed -i '/polybar\/launch.sh/i exec_always --no-startup-id $HOME/.fehbg' ~/.config/i3/config
tail -2 ~/.config/i3/config

The two lines end the file in this order:

exec_always --no-startup-id $HOME/.fehbg
exec_always --no-startup-id $HOME/.config/polybar/launch.sh

Restart i3 in place. Open windows stay where they are:

i3-msg restart

The bar appears at the top of the screen. Read its log:

cat "$XDG_RUNTIME_DIR"/polybar-*.log

The script appends with tee -a, so the file keeps every earlier start. This is a fresh log from a single start: every module loads, both fonts resolve, and no pixmap warning appears. On Fedora 45 the icon font resolves to Font Awesome 7:

polybar|notice:  Parsing config file: /home/josphat/.config/polybar/config.ini
polybar|notice:  Listening for IPC messages (PID: 6302)
polybar|notice:  Loading module 'xworkspaces' of type 'internal/xworkspaces'
polybar|notice:  Loading module 'xwindow' of type 'internal/xwindow'
polybar|notice:  Loading module 'filesystem' of type 'internal/fs'
polybar|notice:  Loading module 'pulseaudio' of type 'internal/pulseaudio'
polybar|notice:  pulseaudio: using default sink auto_null
polybar|notice:  Loading module 'memory' of type 'internal/memory'
polybar|notice:  Loading module 'cpu' of type 'internal/cpu'
polybar|notice:  Loading module 'wlan' of type 'internal/network'
polybar|error: Disabling module "wlan" (reason: No interface found for type 'wireless')
polybar|notice:  Loading module 'eth' of type 'internal/network'
polybar|notice:  module/eth: Discovered wired interface eth0
polybar|notice:  Loading module 'date' of type 'internal/date'
polybar|notice:  Loading module 'systray' of type 'internal/tray'
polybar|notice:  Loaded 9 modules
polybar|notice:  Loaded font "JetBrains Mono:size=10" (name=JetBrains Mono, offset=2, file=/usr/share/fonts/jetbrains-mono-fonts/JetBrainsMono-Regular.otf)
polybar|notice:  Loaded font "Font Awesome 7 Free,Font Awesome 6 Free:style=Solid:size=10" (name=Font Awesome 7 Free, offset=2, file=/usr/share/fonts/fontawesome-7-free-fonts/Font Awesome 7 Free-Solid-900.otf)

The only error left is the wireless module, because the VM has no Wi-Fi card. On a laptop it shows the network name and, unlike the wired module edited above, the local IP address too. This is Fedora 45 with the default wallpaper:

Polybar on top of an i3 desktop on Fedora 45 with the default wallpaper

Up close, the icons come from Font Awesome and the text from JetBrains Mono. The underlined workspace is the focused one, and the tray holds the NetworkManager and PulseAudio applets that the i3 group autostarts:

Close-up of Polybar modules showing disk, volume, memory, CPU, network and clock icons

The same config on Fedora 44, with two terminals open on workspace 2 and the window title shown on the left:

Polybar with i3 workspaces and two terminals on Fedora 44

The terminal on the right runs fish with the bobthefish theme. Our guide to fish and Oh My Fish on Fedora sets that up.

Control the bar with polybar-msg

The sample config sets enable-ipc = true, so a running bar takes commands. Hide and show it:

polybar-msg cmd toggle

Each call reports the process it reached:

Successfully wrote command 'toggle' to PID 4399

Modules accept actions too. This flips the clock between the short and long date formats, the same as clicking it:

polybar-msg action "#date.toggle"

Bind the toggle to a key for full-screen work. The Fedora i3 config in /etc/i3/config uses Alt as the modifier, and Alt+b is free. If the wizard wrote your config and you chose the Win key, use $mod+b instead:

echo 'bindsym Mod1+b exec --no-startup-id polybar-msg cmd toggle' >> ~/.config/i3/config
i3-msg reload

Press Alt+b once to hide the bar and again to bring it back. Two more options are handy while you tune the config. polybar --dump=height main prints a resolved setting and exits. polybar --png=bar.png main saves a snapshot after three seconds, which is easier to share than a cropped screenshot.

Remove Polybar and bring i3bar back

Undo the i3 changes first, so the next restart does not try to run a missing binary. Delete the launcher and wallpaper lines, then uncomment the bar block:

sed -i '/polybar/d; /\.fehbg/d' ~/.config/i3/config
sed -i '/^# bar {/,/^# }/ s/^# //' ~/.config/i3/config

The first command also removes the Alt+b binding, since it mentions polybar. Stop the running bar and restart i3:

polybar-msg cmd quit
i3-msg restart

i3bar returns at the bottom of the screen. Now remove the package:

sudo dnf remove polybar

dnf takes the two libraries with it:

Package       Arch   Version         Repository      Size
Removing:
 polybar      x86_64 0:3.7.2-10.fc45 fedora       2.8 MiB
Removing unused dependencies:
 jsoncpp      x86_64 0:1.9.6-3.fc44  fedora     285.6 KiB
 libmpdclient x86_64 0:2.26-2.fc45   fedora     193.4 KiB

Transaction Summary:
 Removing:           3 packages

After this operation, 3 MiB will be freed (install 0 B, remove 3 MiB).
Running transaction
[1/4] Prepare transaction               100% |  47.0   B/s |   3.0   B |  00m00s
[2/4] Removing polybar-0:3.7.2-10.fc45. 100% |   4.7 KiB/s | 111.0   B |  00m00s
[3/4] Removing jsoncpp-0:1.9.6-3.fc44.x 100% |   3.3 KiB/s |  10.0   B |  00m00s
[4/4] Removing libmpdclient-0:2.26-2.fc 100% |  70.0   B/s |  12.0   B |  00m00s
Complete!

Your config and launch script stay in ~/.config/polybar, ready for a reinstall.

Polybar error messages and fixes

These are the messages we hit while building this setup, with the cause of each.

Undefined bar: main. Available bars: example

Polybar read a config that has no [bar/main] section. Usually ~/.config/polybar/config.ini is missing or misnamed, so Polybar fell back to the sample in /etc. Forcing the sample reproduces it:

polybar -c /etc/polybar/config.ini main

The error lists the bars that file does define:

polybar|notice:  Parsing config file: /etc/polybar/config.ini
polybar|error: Uncaught exception, shutting down: Undefined bar: main. Available bars: example

Check the path, and check that the bar name in the launch script matches the section header.

Disabling module “pulseaudio” (reason: Could not connect pulseaudio context.)

Fedora runs PipeWire with its PulseAudio server per user, and the socket lives under XDG_RUNTIME_DIR. Started from an SSH session or a cron job without that variable, Polybar cannot find it. Started by i3, it connects and logs the default sink, as in the log above.

Disabling module “wlan” (reason: No interface found for type ‘wireless’)

The machine has no wireless card, or the card is not up. It is harmless. On a desktop without Wi-Fi, drop wlan from modules-right to quiet the log.

background_manager: Failed to get root pixmap, default to black

pseudo-transparency = true in the sample config copies the wallpaper behind the bar, and there is no wallpaper yet. Set one with feh before Polybar starts, as shown earlier, or set pseudo-transparency = false under [settings].

Icons show as empty boxes

The icon font name in config.ini does not exist on this release, and fontconfig substituted a text font. Polybar logs the font it actually loaded, so check the Loaded font lines first. Use the Font Awesome 7 and 6 family list from this guide rather than a single name. For other icon sets, the Nerd Fonts guide covers patched fonts that bundle text and icons in one family. If you are still building out the rest of the desktop, our Fedora 45 post-install checklist and the terminal emulator roundup are good next stops.

Keep reading

How to Upgrade Fedora 44 to Fedora 45 (GUI, CLI and Rollback) Fedora How to Upgrade Fedora 44 to Fedora 45 (GUI, CLI and Rollback) Enable RPM Fusion and Install Multimedia Codecs on Fedora 45 / 44 / 43 Fedora Enable RPM Fusion and Install Multimedia Codecs on Fedora 45 / 44 / 43 Backup and Restore Linux Systems with Timeshift Debian Backup and Restore Linux Systems with Timeshift Switch Fedora From GRUB to systemd-boot With bootctl Fedora Switch Fedora From GRUB to systemd-boot With bootctl DNF5 Cheatsheet for Fedora 45 / 44: Tested Commands and Fixes Fedora DNF5 Cheatsheet for Fedora 45 / 44: Tested Commands and Fixes Best Open Source Download Manager Applications for Linux Users Desktop Best Open Source Download Manager Applications for Linux Users

Leave a Comment

Press ESC to close