Fixing BenQ Display Pilot 2 I2C Input/Output Errors on Linux

5 min read

Running Display Pilot 2 on my Arch Linux via the display-pilot-2 AUR package results in the following i2c errors, which prevent Display Pilot 2 from communicating to the BenQ monitor.

W 13:41:04.666 [MonitorModel] getVCP failed "df"
I 13:41:04.666 [MonitorModel] Test VCP failed, waiting for retry.
Ioctl write i2c error:: Input/output error
Ioctl read i2c error:: Input/output error
Ioctl write i2c error:: Input/output error
Ioctl read i2c error:: Input/output error
Ioctl write i2c error:: Input/output error
Ioctl read i2c error:: Input/output error
W 13:41:05.529 [MonitorModel] getVCP failed "df"
I 13:41:05.529 [MonitorModel] Test VCP failed, waiting for retry.
Ioctl write i2c error:: Input/output error
Ioctl read i2c error:: Input/output error
Ioctl write i2c error:: Input/output error
Ioctl read i2c error:: Input/output error
Ioctl write i2c error:: Input/output error
Ioctl read i2c error:: Input/output error
W 13:41:06.391 [MonitorModel] getVCP failed "df"
I 13:41:06.391 [MonitorModel] Test VCP failed, waiting for retry.

If you are seeing such errors, first make sure that your $USER is a member of the i2c group. You can use the groups(1) command to check that.

groups

If your $USER is not a member of the i2c group can add yourself to the group using the following command.

sudo usermod -aG i2c $USER

You will need to logout and login again for the changes to take effect. Once you login back start Display Pilot 2 again and if the errors are gone, you can stop reading at this point, otherwise continue forward.

The reason why Display Pilot is failing with these errors is because it is using the wrong i2c device for communicating with the monitor. In order to confirm that we need to check what Display Pilot 2 is using and what is the actual i2c device for communication with our monitor. We will need ddcutil(1), so make sure that you have it installed first.

sudo pacman -S ddcutil

Then use the following command to detect monitors that have Virtual Control Panel.

ddcutil detect

On my system the result from the above ddcutil(1) looks like this.

$ ddcutil detect
Display 1
   I2C bus:  /dev/i2c-6
   DRM_connector:           card1-DP-1
   EDID synopsis:
      Mfg id:               BNQ - UNK
      Model:                BenQ RD280UG
      Product code:         32959  (0x80bf)
      Serial number:        EMF6T00355087
      Binary serial number: 16843009 (0x01010101)
      Manufacture year:     2026,  Week: 25
   VCP version:         2.2

We can see that the BenQ RD280UG monitor is available at the /dev/i2c-6 bus. Double check that the device permissions are correct and that the i2c group can read and write to that device.

$ ls -la /dev/i2c-6
crw-rw----+ 1 root i2c 89, 6 Oct 10 14:00 /dev/i2c-6

Now we will check what is the i2c device that Display Pilot 2 is actually using. In order to do that we will first extract the AppImage contents of the Display Pilot 2 app and strace(1) it. Create a temporary workdir, where will extract the contents of the AppImage.

mkdir workdir && cd workdir
display-pilot-2 --appimage-extract

We can now strace(1) the program using the following command and see what is the i2c device that it is using.

strace -f -e trace=openat,ioctl -o display-pilot.log ./squashfs-root/AppRun

Let the strace(1) command above run for a while, so we can capture any openat(3) syscalls and after a short period of time stop the tracing. We can now inspect the display-pilot.log file and see what i2c device is being used by it.

$ grep i2c display-pilot.log
14039 openat(AT_FDCWD, "/dev/i2c-2", O_RDWR) = 41
14039 openat(AT_FDCWD, "/dev/i2c-2", O_RDWR) = 41
14039 openat(AT_FDCWD, "/dev/i2c-2", O_RDWR) = 41
14039 openat(AT_FDCWD, "/dev/i2c-2", O_RDWR) = 41
14039 openat(AT_FDCWD, "/dev/i2c-2", O_RDWR) = 41
14039 openat(AT_FDCWD, "/dev/i2c-2", O_RDWR) = 41
...

And this is the actual issue – we have confirmed with ddcutil(1) that the BenQ monitor is available at the /dev/i2c-6 device, but the Display Pilot 2 app is trying to communicate with the monitor via the /dev/i2c-2 device.

In order to fix the Display Pilot 2 app we will symlink /dev/i2c-6 to the /dev/i2c-2 device used by the app via systemd unit. Make sure that you use the correct /dev/i2c-* devices on your system for the systemd unit below.

# /etc/systemd/system/benq-i2c-fix.service
[Unit]
Description=Fix BenQ Display Pilot 2 I2C Routing
After=systemd-modules-load.service

[Service]
Type=oneshot
ExecStartPre=/usr/bin/rm -f /dev/i2c-2
ExecStart=/usr/bin/ln -s /dev/i2c-6 /dev/i2c-2
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Reload the systemd daemon, then enable and start the benq-i2c-fix.service.

sudo systemctl daemon-reload
sudo systemctl enable --now benq-i2c-fix.service

Confirm that /dev/i2c-2 is a symlink to /dev/i2c-6.

$ ls -l /dev/i2c-2
lrwxrwxrwx 1 root root 10 Oct 10 14:50 /dev/i2c-2 -> /dev/i2c-6

At this point Display Pilot 2 should start up fine and talk to the correct i2c device.

Written on October 10, 2026