Welcome to the Streamlit community, Sudipta! Thanks for sharing your question and code snippet—this is a common issue when moving from local development to cloud deployment.
The main reason for intermittent image loading on Streamlit Community Cloud is usually related to file path handling and file availability. On the cloud, your app’s working directory is the root of your GitHub repo, and any local paths (like those on your machine) may not exist or persist between sessions. To ensure consistent behavior:
Make sure your images are included in your GitHub repo and use paths relative to the repo root, not absolute or local machine paths.
For dynamic or user-uploaded images, use Streamlit’s static file serving by placing images in a ./static/ folder and enabling static serving in .streamlit/config.toml (enableStaticServing = true). Then, access images via the /app/static/ path.
Avoid relying on files written at runtime, as these may not persist across sessions on the cloud.
For example, to display an image reliably:
import streamlit as st
from PIL import Image
# If your image is in the static folder
image_path = "app/static/specific_image.jpg"
st.image(image_path)
Or, if you must use PIL:
from PIL import Image
image = Image.open("app/static/specific_image.jpg")
st.image(image)
However I have an issue in using the ./static/ directory since I save and retrieve images dynamically from a Network File Server (NFS) mounted directory. This is because I have my streamlit app running on multiple compute instances in the cloud. Moreover the streamlit server runs in docker container.
The generated image files are being stored correctly. However, st.images sometimes displays them, sometimes it doesn’t.
My eyes fixate here and I wonder how you are handling your files exactly. It’s important to know that the file system is shared among all users so this type of pattern can easily lead to unintentional conflicts. Are you manually handling your image names? Using tempfile?
My intuition is that you should either use tempfileto make sure things are clean or store the bytes directly in Session State (size permitting).
As I mentioned earlier, the file is not the issue. The files are saved in an NFS mounted directory with separate space for each user. NFS resolves conflicts if any.
The issue is with rendering the image using st.imgae(). i have tried session state variables to store the images too.
I see the error
2026-03-20 19:39:21.226 MediaFileHandler: Missing file 52d7ebe80d83374e8a176ee431cb6a5d462b099beef269bd2315ad3f.jpg
Seems this is connected to the issue.
The MediaFileHandler is what Streamlit uses internally to host a file that you pass to it. Please can you share in more detail how you are handling the files? I’m wondering about the precise timing of everything with your file writes and reads. Is your app authenticated with each user uniquely and persistently identified, even if they return later? (In which case, what happens when a single user has multiple tabs/sessions running?)
This is because I have my streamlit app running on multiple compute instances in the cloud.
This is another thing that might introduce complexity, and it would help to have the full picture in more detail. If you have a user reconnect to a session ever, and if you don’t specifically handle it, they can reconnect to a different instance of the Streamlit server and get some unintended effects.
To be clear, I’m not talking about them logging in again; I’m talking about an interruption in their WebSocket connection. If a user is active in a session, under certain circumstances, they could find themselves “reconnected” to a different server instance.
You mentioned previously having a lock but abandoning that. I am assuming your NFS lives completely outside of each Streamlit server’s file system. So what happens when the same user runs your app in two different tabs (and thus two different sessions, possibly connected to two different Streamlit server instances)?
I think we are digressing from the main issue here - intermittent rendering of images using st.image().
This happens even if I don’t save to a file.
Can you suggest a solution for that?
Passing the image directly as bytes seems the most robust. You could test using an inline custom component to display the image instead of st.image to display the file as raw bytes. That would bypass the MediaFileHandler.
Yes, bypassing the image handler is the key.
I used the following code to convert to base64 string.:
`import base64
import mimetypes
def media_to_data_uri(file_path):
“”"
Converts a media file to a Base64 data URI string.
Args:
file_path (str): The path to the media file.
Returns:
str: The complete Base64 data URI.
"""
# Determine the MIME type of the file
mime_type, _ = mimetypes.guess_type(file_path)
if mime_type is None:
mime_type = 'application/octet-stream' # Default if type is unknown
# Read the file in binary mode and encode to base64
try:
with open(file_path, "rb") as f:
encoded_bytes = base64.b64encode(f.read())
encoded_string = encoded_bytes.decode('utf-8')
except FileNotFoundError:
return f"Error: File not found at {file_path}"
except Exception as e:
return f"Error reading file: {e}"
# Construct the data URI
data_uri = f"data:{mime_type};base64,{encoded_string}"
return data_uri`
This works for me.
Wondering if this would work for PDFs.
I’m suggesting you create a custom component to fit your need. It’s just a way to inject raw HTML, JavaScript, and CSS. There is also st.html for just HTML.
I would be curious to see if you swap in a raw <img> and pass the Base64 string if you still get the problem or not.
For the sake of investigation, let’s assume your NFS is completely correct and always accessible to all user sessions with no file conflicts or interference from multiple user sessions:
Let PATH be the path of an image file you want to display. Can you update your app and check it’s behavior in deployment with this “triple image dispaly” to confirm if they fail in unison or not?
import streamlit as st
import base64
PATH = 'star.jpg'
image_format = "jpg"
with open(PATH, "rb") as f:
bytes_string = f.read()
b64 = base64.b64encode(bytes_string).decode('utf-8')
st.image(PATH)
st.image(bytes_string)
st.html(f"<img src='data:image/{image_format};base64,{b64}' style='width:100%;'> ")