Troubleshooting
Diagnose and fix common runtime errors. Entries are organised by error type.
OSError: [Errno 121] Remote I/O error
Cause: The slave device did not acknowledge (ACK) the I2C address or a data byte. This is almost always caused by:
Incorrect wiring (SDA/SCL swapped, missing pull-up resistors).
Wrong I2C device address.
Wrong command sequence — e.g. sending a register byte to a device that does not expect one.
Device not powered or not yet ready.
Resolution:
Verify wiring and confirm pull-up resistors are present on SDA and SCL (typically 4.7 kΩ to 3.3 V or 5 V, depending on the bus voltage).
Scan for the device address:
i2cdetect -y 1(replace1with your bus number).Check the kernel log for driver-level messages:
dmesg | grep -i i2c
If the device has no register-addressing concept, switch from
*_datafunctions toi2c_rdwr— see Prefer i2c_rdwr for Devices That Do Not Use the Register-Address Protocol.For devices like the AHT25/DHT20, use a write-then-read pattern (#110):
write = i2c_msg.write(0x38, [0xac, 0x33, 0x00]) read = i2c_msg.read(0x38, 6) bus.i2c_rdwr(write, read)
OSError: [Errno 5] Input/output error
Cause: A bus-level error — the slave NAK’d a data byte (not just the address), electrical noise disrupted the transaction, or the master timed out waiting for clock stretching to complete.
Resolution:
Check pull-up resistor values (too high → marginal signalling).
Reduce the I2C clock speed via the kernel driver (see Setting I2C Bus Clock Speed (Baud Rate)).
Add a small delay between operations — see Add Small Delays Between Operations on Slow Devices.
Check
dmesg | grep i2cforsendbytes: NAK bailoutmessages (#110).
ModuleNotFoundError: No module named 'fcntl'
Cause: fcntl is a Linux-only standard library module. smbus2 imports it at
startup and will fail with this error on Windows or macOS
(#73).
Resolution: smbus2 only runs on Linux. There is no supported workaround for other operating systems. If you need I2C access on macOS or Windows, consider hardware bridges such as CP2112 or MCP2221 with their respective vendor Python libraries.
SystemError: buffer overflow (Python 3.14+)
Cause: On Python 3.14+ running on 64-bit systems, the I2C_FUNCS ioctl used
c_uint32 for the output buffer, which is too small for 64-bit kernels, causing a
buffer overflow
(#124).
Resolution: Upgrade smbus2 to v0.6.0 or later. The fix changes the internal
c_uint32 to c_ulong, which matches the kernel’s expected buffer size.
pip install --upgrade smbus2
Reads Return Unexpected Values or Incorrect Data
Possible causes and resolutions:
Wiring — check connections; poor contact or loose wires cause intermittent errors.
Wrong address — run
i2cdetect -y 1to confirm the device address.Wrong byte count — some devices return a length byte as the first byte of a block read; the actual data starts at index 1 (#68).
Register-byte confusion — if the device does not use register addressing, the
*_datafunctions send an unwanted write before the read, corrupting device state. Usei2c_rdwrinstead (#115, #101).Endianness — the word may be big-endian; see Endianness / Byte-Order Conversion.
Signed vs. unsigned — all values are returned unsigned; convert with
ctypesif needed; see Signed Integer Conversion.
Very Slow Reads (read_byte_data, read_i2c_block_data)
Cause: smbus2 itself adds negligible overhead. Slowness is almost always caused by:
The Linux kernel I2C driver (clock speed, scheduling latency).
Clock stretching by the slave device holding SCL low.
A driver bound to the device blocking the
ioctlcall (#76, #108).
Resolution:
Try
force=Trueon the call if a kernel driver is already bound to the device address (use with caution — bypasses driver safety).Reduce the I2C clock speed so the device has more time per bit.
For high-throughput scenarios consider batching reads with
i2c_rdwr.