How to Resolve Python "io.UnsupportedOperation: not readable / not writable"
When working with files in Python using the built-in open()
function, you might encounter io.UnsupportedOperation: not readable
or io.UnsupportedOperation: not writable
. These errors indicate a mismatch between the mode you used to open the file and the operation (reading or writing) you attempted to perform on the file handle.
This guide explains the different file modes, why these errors occur, and how to choose the correct mode to fix them.
Understanding the Error: File Modes and Allowed Operations
When you open a file using open(filename, mode)
, the mode
argument specifies how you intend to interact with the file. Common modes include:
'r'
: Read (default)'w'
: Write (truncates file if exists, creates if not)'a'
: Append (writes to end, creates if not)'rb'
,'wb'
,'ab'
: Corresponding binary modes.'+'
: Added to a mode (e.g.,'r+'
,'w+'
,'a+'
) to allow both reading and writing (updating).
The UnsupportedOperation
error occurs when the operation you attempt (e.g., file.read()
, file.write()
) is not permitted by the mode
the file was opened with.
Error 1: io.UnsupportedOperation: not readable
Cause: Trying to Read a File Opened Only for Writing ('w'
, 'a'
)
You opened the file using a mode intended only for writing ('w'
) or appending ('a'
), and then tried to call a read method like read()
, readline()
, or readlines()
.
import os # For file cleanup later
filename = "example_write.txt"
# Ensure file exists for demo
with open(filename, 'w', encoding='utf-8') as f:
f.write("Initial line.\n")
# Error Scenario: Opened with 'w', trying to read
try:
with open(filename, 'w', encoding='utf-8') as f_write:
print(f"Opened '{filename}' with mode 'w'.")
# File is truncated upon opening with 'w'
f_write.write("New content.\n")
# ⛔️ io.UnsupportedOperation: not readable
content = f_write.read() # Cannot read in 'w' mode
print("Content:", content)
except io.UnsupportedOperation as e:
print(f"Caught Error: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
finally:
if os.path.exists(filename): os.remove(filename) # Clean up file
Mode 'w'
and 'a'
do not allow read operations.
Solution: Open in Read Mode ('r'
)
If your primary goal is just to read the file, open it using mode='r'
(or simply omit the mode, as 'r'
is the default). Remember to specify encoding
.
import os
filename = "example_read.txt"
# Create file with content
with open(filename, 'w', encoding='utf-8') as f:
f.write("Line 1\n")
f.write("Line 2\n")
# Solution: Open with 'r' for reading
try:
# ✅ Use mode='r' (or omit mode) and specify encoding
with open(filename, 'r', encoding='utf-8') as f_read:
print(f"\nOpened '{filename}' with mode 'r'. Reading content:")
content = f_read.read()
print("--- File Content ---")
print(content, end='') # Print content as read
print("--- End Content ---")
except FileNotFoundError:
print(f"Error: File '{filename}' not found.")
except Exception as e:
print(f"An unexpected error occurred: {e}")
finally:
if os.path.exists(filename): os.remove(filename)
Example Output:
Opened 'example_read.txt' with mode 'r'. Reading content:
--- File Content ---
Line 1
Line 2
--- End Content ---
Solution: Open in Read/Write Mode ('r+'
, 'a+'
)
If you genuinely need to both read and write to the same file within the same open()
block, use a mode with a +
:
'r+'
: Opens for reading and writing. The file must exist. The file pointer starts at the beginning. Writing may overwrite existing content depending on the position.'a+'
: Opens for reading and appending. Creates the file if it doesn't exist. The file pointer starts at the end for writing (appending), but you can move it (seek()
) for reading.
import os
filename = "example_plus.txt"
# Create file initially
with open(filename, 'w', encoding='utf-8') as f: f.write("Existing data.\n")
# Solution: Using 'a+' mode (read and append)
try:
# ✅ Use mode='a+' for reading and appending
with open(filename, 'a+', encoding='utf-8') as f_append_read:
print(f"\nOpened '{filename}' with mode 'a+'.")
# Current position is at the end, so read() gets nothing initially
print(f"Content read immediately: '{f_append_read.read()}'")
# Append new data
f_append_read.write("Appended line 1.\n")
f_append_read.write("Appended line 2.\n")
print("Appended data.")
# Move pointer to the beginning to read everything
f_append_read.seek(0)
print("Reading all content after seeking to start:")
all_content = f_append_read.read()
print("--- Full Content ---")
print(all_content, end='')
print("--- End Content ---")
except FileNotFoundError: # Should not happen with 'a+'
print(f"Error: File '{filename}' could not be created/opened.")
except Exception as e:
print(f"An unexpected error occurred: {e}")
finally:
if os.path.exists(filename): os.remove(filename)
Example Output:
Opened 'example_plus.txt' with mode 'a+'.
Content read immediately: ''
Appended data.
Reading all content after seeking to start:
--- Full Content ---
Existing data.
Appended line 1.
Appended line 2.
--- End Content ---
Remember f.seek(0)
is needed to read from the start after opening with 'a+'
.
Error 2: io.UnsupportedOperation: not writable
Cause: Trying to Write to a File Opened Only for Reading ('r'
)
You opened the file using mode='r'
(read-only) and then tried to call write()
.
import os
filename = "example_readonly.txt"
# Create file
with open(filename, 'w', encoding='utf-8') as f: f.write("Read me.\n")
# Error Scenario: Opened with 'r', trying to write
try:
with open(filename, 'r', encoding='utf-8') as f_read:
print(f"\nOpened '{filename}' with mode 'r'.")
content = f_read.read() # Reading is allowed
print(f"Read content: {content.strip()}")
# ⛔️ io.UnsupportedOperation: not writable
f_read.write("Trying to write.\n") # Cannot write in 'r' mode
except io.UnsupportedOperation as e:
print(f"Caught Error: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
finally:
if os.path.exists(filename): os.remove(filename)
Solution: Open in Write Mode ('w'
, 'a'
)
If your goal is only to write (overwriting) or append, use the appropriate write-only mode.
'w'
(Write/Overwrite): Opens for writing. Truncates (empties) the file if it exists. Creates the file if it doesn't exist.# ✅ Use mode='w' to overwrite/write fresh
with open(filename, 'w', encoding='utf-8') as f_write:
print(f"\nOpened '{filename}' with mode 'w'. Writing...")
f_write.write("New content line 1.\n")
f_write.write("New content line 2.\n")
print("Write successful.")
# File now contains only the two new lines.'a'
(Append): Opens for writing. Appends to the end if the file exists. Creates the file if it doesn't exist.# ✅ Use mode='a' to add to the end
with open(filename, 'a', encoding='utf-8') as f_append:
print(f"\nOpened '{filename}' with mode 'a'. Appending...")
f_append.write("Appended content.\n")
print("Append successful.")
# File now contains previous content PLUS the appended line.
Solution: Open in Read/Write Mode ('r+'
, 'a+'
)
As described in Solution 2.3, use 'r+'
or 'a+'
if you need to perform both read and write operations in the same block.
Common File Modes Explained (Table)
Mode | Description | Behavior if File Exists | Behavior if File Doesn't Exist | Read? | Write? | Initial Position |
---|---|---|---|---|---|---|
r | Read only (text) | Opens | FileNotFoundError | Yes | No | Beginning |
w | Write only (text) | Truncates (Empties!) | Creates | No | Yes | Beginning |
a | Append only (text) | Opens | Creates | No | Yes | End |
r+ | Read and Write (text) | Opens | FileNotFoundError | Yes | Yes | Beginning |
a+ | Read and Append (text) | Opens | Creates | Yes | Yes | End (for write) |
rb | Read only (binary) | Opens | FileNotFoundError | Yes | No | Beginning |
wb | Write only (binary) | Truncates (Empties!) | Creates | No | Yes | Beginning |
ab | Append only (binary) | Opens | Creates | No | Yes | End |
rb+ | Read and Write (binary) | Opens | FileNotFoundError | Yes | Yes | Beginning |
ab+ | Read and Append (binary) | Opens | Creates | Yes | Yes | End (for write) |
Using with open()
(Recommended) vs. Manual open()
/close()
with open(...) as f:
: This is the preferred Pythonic way. It guarantees that the file (f
) is automatically closed when thewith
block is exited, even if errors occur inside the block. This prevents resource leaks.f = open(...)
: If you useopen()
directly, you are responsible for closing the file usingf.close()
. Forgetting to close files can lead to problems, especially in long-running applications. Use atry...finally
block to ensureclose()
is always called.
Importance of encoding
When opening files in text mode ('r'
, 'w'
, 'a'
, 'r+'
, 'a+'
), always specify the encoding
argument (e.g., encoding='utf-8'
). This tells Python how to translate the bytes stored on disk into the strings your program works with (and vice-versa). Omitting it makes Python use a system-dependent default, which can lead to errors (UnicodeDecodeError
, UnicodeEncodeError
) or incorrect data if the file's actual encoding doesn't match the default. 'utf-8'
is a very common and good default choice. Do not use encoding
with binary modes ('rb'
, 'wb'
, etc.).
Conclusion
The io.UnsupportedOperation: not readable
and io.UnsupportedOperation: not writable
errors directly result from attempting a file operation not permitted by the mode
used in the open()
function.
- If you get
not readable
, you likely opened with'w'
or'a'
. Change the mode to'r'
(for reading only) or'r+'
/'a+'
(for reading and writing). - If you get
not writable
, you likely opened with'r'
. Change the mode to'w'
(to overwrite),'a'
(to append), or'r+'
/'a+'
(for reading and writing).
Always choose the file mode that accurately reflects the operations you intend to perform and use the with open(...)
statement with explicit encoding
for safe and correct file handling in text mode.