How does streamlit access media files?

When I run my streamlit app (deployed in cloud) when I click st.download_button it shows me:

2026-06-17 14:47:32.803 200 GET /media/883802cc33ba652d752ebaf82e8bea14ef913f4175e878affbe1566c.pdf (10.116.0.6) 3.47ms

In the logs.

However the the download fails with the browser complaining 404 error, not found.

Can you explain what this media file is and why it cannot be found?

The download code is as follows:

 pdf_path = os.path.join(st.session_state.image_path, "Analysis_Report.pdf")
        PDFbyte = None
        if os.path.isfile(pdf_path):
            with open(pdf_path, "rb") as pdf_file:
                PDFbyte = pdf_file.read()
        if PDFbyte:
            tm.sleep(6)
            st.download_button(
            label="PDF Report",
            data=PDFbyte,
            #data=pdf_file,
            file_name= idea_id+"_Analysis_Report.pdf",
            mime="application/pdf",
            #mime = "application/octet-stream",
            key = "pdf_download",
            on_click='ignore',
            icon = ":material/download:",
            )
        else:
            st.error("Analysis Report PDF not created.")

This code works sometimes but it is a hit or miss.

Quite frustrated.

Sudipta Bhawmik

Welcome to the Streamlit community, Sudipta! Thanks for sharing your question and code snippet—this is a common frustration, especially when moving from local to cloud deployments. The /media/… path in your logs refers to Streamlit’s internal media file storage, which temporarily holds files for download via st.download_button. A 404 error means the file isn’t available when the browser tries to fetch it, often because the file was deleted, moved, or not properly loaded into memory before the download button was rendered.

This issue is frequently caused by timing or session management problems—such as the file being closed, garbage-collected, or not present on the server instance handling the request (especially in cloud environments with multiple replicas). To ensure reliability, always read the file fully into memory (as bytes) before passing it to st.download_button, and avoid delays (like tm.sleep) between reading the file and rendering the button. Also, avoid relying on files written to disk, as cloud environments may not persist files between reruns or across server replicas. Instead, use in-memory objects (like io.BytesIO) and reset their pointer with seek(0) before passing to the download button. For more details and robust patterns, see the Streamlit docs for st.download_button and forum discussions on download issues.

Sources: