Skip to content

How to Resolve Python "io.UnsupportedOperation: not readable / not writable"

Fix Python's 'io.UnsupportedOperation' errors when trying to read from a file opened in write mode ('w', 'a') or write to a file opened in read mode ('r') by selecting the correct open() mode.

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"
with open(filename, 'w', encoding='utf-8') as f:
    f.write("Initial line.\n")

try:
    with open(filename, 'w', encoding='utf-8') as f_write:
        print(f"Opened '{filename}' with mode 'w'.")
        f_write.write("New content.\n")
        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"
with open(filename, 'w', encoding='utf-8') as f:
    f.write("Line 1\n")
    f.write("Line 2\n")

try:
    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"
with open(filename, 'w', encoding='utf-8') as f: f.write("Existing data.\n")

try:
    with open(filename, 'a+', encoding='utf-8') as f_append_read:
        print(f"\nOpened '{filename}' with mode 'a+'.")
        print(f"Content read immediately: '{f_append_read.read()}'")

        f_append_read.write("Appended line 1.\n")
        f_append_read.write("Appended line 2.\n")
        print("Appended data.")

        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"
with open(filename, 'w', encoding='utf-8') as f: f.write("Read me.\n")

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()}")
        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.
    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.")
  • 'a' (Append): Opens for writing. Appends to the end if the file exists. Creates the file if it doesn't exist.
    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.")

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)
  • with open(...) as f:: This is the preferred Pythonic way. It guarantees that the file (f) is automatically closed when the with block is exited, even if errors occur inside the block. This prevents resource leaks.
  • f = open(...): If you use open() directly, you are responsible for closing the file using f.close(). Forgetting to close files can lead to problems, especially in long-running applications. Use a try...finally block to ensure close() 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.

Navigation