Skip to main content

Sometimes I get `HTTP Error 401: Unauthorized` when trying to export to YouTube

Thanks for adding Youtube export. Very handy.
Though sometimes, I get a status 401 error. Disconnecting & re-connecting to Youtube fixes it. Here’s the logs for it:

19:02:19.504 DEBUG hosaka.core.ffmpeg:849 - Starting FFmpeg encoder: ffmpeg -y -loglevel warning -f rawvideo -pix_fmt bgr24 -s 1366x768 -r 60 -i pipe:0 -i /tmp/hosaka_audio_2_47d5d0b2.wav -c:v libopenh264 -b:v 8000000 -g 30 -profile:v high -pix_fmt yuv420p -map 0:v -map 1:a -c:a aac -b:a 192k -movflags frag_keyframe+empty_moov -f mp4 pipe:1
19:02:19.505 DEBUG hosaka.core.ffmpeg:870 - FFmpeg encoder started (PID: 221)
19:02:19.505 DEBUG hosaka.pipeline.export:170 - Export initialization complete
19:02:19.505 DEBUG hosaka.pipeline.export:589 - Export initialized successfully
19:02:20.416 ERROR hosaka.ui.workers.export:221 - Streaming export+upload failed: HTTP Error 401: Unauthorized
Traceback (most recent call last):
  File "/app/lib/python3.12/site-packages/hosaka/ui/workers/export.py", line 183, in _run_streaming
    exporter.export_recording(
  File "/app/lib/python3.12/site-packages/hosaka/pipeline/export.py", line 592, in export_recording
    on_encoder_started()
  File "/app/lib/python3.12/site-packages/hosaka/ui/workers/export.py", line 175, in on_encoder_started
    coordinator.start(original_output_path.name)
  File "/app/lib/python3.12/site-packages/hosaka/core/streaming_upload.py", line 47, in start
    self._provider.start_streaming_upload(filename, content_type)
  File "/app/lib/python3.12/site-packages/hosaka/core/youtube_upload.py", line 230, in start_streaming_upload
    with urllib.request.urlopen(request, timeout=HTTP_TIMEOUT) as response:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/urllib/request.py", line 215, in urlopen
    return opener.open(url, data, timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/urllib/request.py", line 521, in open
    response = meth(req, response)
               ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/urllib/request.py", line 630, in http_response
    response = self.parent.error(
               ^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/urllib/request.py", line 559, in error
    return self._call_chain(*args)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/urllib/request.py", line 492, in _call_chain
    result = func(*args)
             ^^^^^^^^^^^
  File "/usr/lib/python3.12/urllib/request.py", line 639, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 401: Unauthorized
19:02:20.420 ERROR hosaka.app:1474 - Export failed: HTTP Error 401: Unauthorized
Status: Completed1 comment

Log in to comment and vote

Comments1

  • Hugo Baldwin changed status to Completed
    Team•

    Mar 19

    Pinned

    Thanks for the detailed report and logs - they were very helpful in tracking this down.


    The root cause: Google OAuth2 access tokens expire after 1 hour. If you connected to YouTube and then waited a while before exporting, the stored token would be stale by the time the upload started. The app wasn't checking expiry before using it, so it would try the expired token, get a 401, and give up. Disconnecting and reconnecting issued a fresh token, which is why that workaround worked.

    This is now fixed in v0.1.124. The app now stores the token expiry time and proactively refreshes the access token before starting an export if it's expired or close to expiring - so you shouldn't need to manually reconnect any more.