<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: TranscriptFetch</title>
    <description>The latest articles on DEV Community by TranscriptFetch (@transcriptfetch).</description>
    <link>https://dev.to/transcriptfetch</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4217609%2Ff5bff5a2-f65c-4dbd-b3a3-0b79d5818f37.png</url>
      <title>DEV Community: TranscriptFetch</title>
      <link>https://dev.to/transcriptfetch</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/transcriptfetch"/>
    <language>en</language>
    <item>
      <title>youtube_transcript_api works on my laptop but fails on AWS: a checklist</title>
      <dc:creator>TranscriptFetch</dc:creator>
      <pubDate>Fri, 30 Oct 2026 20:23:31 +0000</pubDate>
      <link>https://dev.to/transcriptfetch/youtubetranscriptapi-works-on-my-laptop-but-fails-on-aws-a-checklist-k6l</link>
      <guid>https://dev.to/transcriptfetch/youtubetranscriptapi-works-on-my-laptop-but-fails-on-aws-a-checklist-k6l</guid>
      <description>&lt;p&gt;If &lt;code&gt;youtube_transcript_api&lt;/code&gt; runs fine locally and starts failing the moment you deploy, it is tempting to blame IP blocking straight away. Often that is the answer, but not always. Here is the order I check things in, cheapest first.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Rule out the video itself
&lt;/h2&gt;

&lt;p&gt;Before touching infrastructure, run the exact failing video ID locally.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Captions disabled by the uploader raise &lt;code&gt;TranscriptsDisabled&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Captions that exist only in another language raise &lt;code&gt;NoTranscriptFound&lt;/code&gt;. List what is there first:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;youtube_transcript_api&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;YouTubeTranscriptApi&lt;/span&gt;

&lt;span class="n"&gt;ytt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;YouTubeTranscriptApi&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ytt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VIDEO_ID&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;language_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_generated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Private, deleted, age restricted or region locked videos fail everywhere, not only in production.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the video fails on your laptop too, it is not your server.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Same video, two networks
&lt;/h2&gt;

&lt;p&gt;Run the identical request, same library version, from your laptop and from the production host. Local works and the server fails on the same ID? The request origin is the difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Read the exception, not just the stack trace
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;RequestBlocked&lt;/code&gt; or &lt;code&gt;IpBlocked&lt;/code&gt;: YouTube is refusing your server's IP. Cloud provider ranges (AWS, GCP, Azure, most VPS hosts) are the usual trigger, and the library's own README says so.&lt;/li&gt;
&lt;li&gt;HTTP 429: rate limiting. Concurrency that was fine locally may not be fine from one egress IP.&lt;/li&gt;
&lt;li&gt;Timeouts and empty results that get worse with volume: also throttling, just quieter.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Check what changed
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Did you upgrade the library? The API moved from static &lt;code&gt;get_transcript&lt;/code&gt; calls to an instance with &lt;code&gt;fetch&lt;/code&gt; and &lt;code&gt;list&lt;/code&gt; in 1.x, so old snippets break.&lt;/li&gt;
&lt;li&gt;Did your platform start rotating or sharing egress IPs (serverless, NAT gateways)?&lt;/li&gt;
&lt;li&gt;Did you add workers or async fan out?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Pick a fix
&lt;/h2&gt;

&lt;p&gt;If it really is the IP, there are three honest options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Stay local or residential.&lt;/strong&gt; For a script you run now and then, run it from a home connection and move on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proxies.&lt;/strong&gt; The library supports them directly:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;youtube_transcript_api&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;YouTubeTranscriptApi&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;youtube_transcript_api.proxies&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;GenericProxyConfig&lt;/span&gt;

&lt;span class="n"&gt;ytt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;YouTubeTranscriptApi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;proxy_config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;GenericProxyConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;http_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://user:pass@proxy.example:8080&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;https_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://user:pass@proxy.example:8080&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ytt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VIDEO_ID&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_raw_data&lt;/span&gt;&lt;span class="p"&gt;()[:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Residential proxies work far better than datacenter ones here. The cost is per GB, and you own rotation, retries and the monitoring for silent failures.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A hosted transcript API.&lt;/strong&gt; Someone else runs the proxy layer and you call an HTTP endpoint. Disclosure: I build one of these, TranscriptFetch, so weigh that. The trade is a per request price against your own time on proxy upkeep.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The short version
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;Fit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Occasional local scripts&lt;/td&gt;
&lt;td&gt;Keep the library, run it locally&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You already run a proxy fleet&lt;/td&gt;
&lt;td&gt;Library plus proxies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A production app, no wish to run proxies&lt;/td&gt;
&lt;td&gt;A hosted API&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The longer write up, with the full error list and code for the hosted route, is on &lt;a href="https://transcriptfetch.com/blog/youtube-transcript-api-not-working-in-production?utm_source=devto&amp;amp;utm_medium=post&amp;amp;utm_campaign=challenger-devto-01" rel="noopener noreferrer"&gt;our blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have hit a failure mode that is not on this list, I would like to hear it in the comments.&lt;/p&gt;

</description>
      <category>python</category>
      <category>youtube</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
