ytdl-org/youtube-dl · error · EmbedThumbnailPPError

AtomicParsley was not found. Please install.

Error message

AtomicParsley was not found. Please install.

What it means

Raised by EmbedThumbnailPP when the file is m4a/mp4 (the AtomicParsley branch) and neither 'AtomicParsley' nor 'atomicparsley' is executable on PATH (checked by running it with -v). Embedding a thumbnail into an MP4 container requires that external tool, so its absence is fatal for this post-processor.

Source

Thrown at youtube_dl/postprocessor/embedthumbnail.py:100

                '-c', 'copy', '-map', '0', '-map', '1',
                '-metadata:s:v', 'title="Album cover"', '-metadata:s:v', 'comment="Cover (Front)"']

            self._downloader.to_screen('[ffmpeg] Adding thumbnail to "%s"' % filename)

            self.run_ffmpeg_multiple_files([filename, thumbnail_filename], temp_filename, options)

            if not self._already_have_thumbnail:
                os.remove(encodeFilename(thumbnail_filename))
            os.remove(encodeFilename(filename))
            os.rename(encodeFilename(temp_filename), encodeFilename(filename))

        elif info['ext'] in ['m4a', 'mp4']:
            atomicparsley = next((x
                                  for x in ['AtomicParsley', 'atomicparsley']
                                  if check_executable(x, ['-v'])), None)

            if atomicparsley is None:
                raise EmbedThumbnailPPError('AtomicParsley was not found. Please install.')

            cmd = [encodeFilename(atomicparsley, True),
                   encodeFilename(filename, True),
                   encodeArgument('--artwork'),
                   encodeFilename(thumbnail_filename, True),
                   encodeArgument('-o'),
                   encodeFilename(temp_filename, True)]

            self._downloader.to_screen('[atomicparsley] Adding thumbnail to "%s"' % filename)

            if self._downloader.params.get('verbose', False):
                self._downloader.to_screen('[debug] AtomicParsley command line: %s' % shell_quote(cmd))

            p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            stdout, stderr = process_communicate_or_kill(p)

            if p.returncode != 0:
                msg = stderr.decode('utf-8', 'replace').strip()

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Install AtomicParsley (Debian/Ubuntu: apt install atomicparsley; macOS: brew install atomicparsley) and confirm 'AtomicParsley -v' runs
  2. If already installed, ensure the binary is on PATH and executable (chmod +x)
  3. Alternatively switch to yt-dlp, which embeds mp4 thumbnails via ffmpeg and needs no extra binary
  4. If you only need thumbnails in audio, download mp3 (uses mutagen ffmpeg path, no AtomicParsley needed)

Example fix

# before: fails with 'AtomicParsley was not found'
youtube-dl --embed-thumbnail https://example.com/video.mp4
# after
sudo apt-get install atomicparsley
youtube-dl --embed-thumbnail https://example.com/video.mp4
Defensive patterns

Strategy: validation

Validate before calling

import shutil

def can_embed_mp4_thumbnail():
    return shutil.which('AtomicParsley') is not None or shutil.which('atomicparsley') is not None

if not can_embed_mp4_thumbnail():
    options['embedthumbnail'] = False  # skip instead of failing the whole job

Try / catch

try:
    ydl.download([url])
except PostProcessingError as e:
    if 'AtomicParsley was not found' in str(e):
        log.warning('Skipping thumbnail embed for %s', url)  # download itself succeeded

Prevention

When it happens

Trigger: Running with --embed-thumbnail on an mp4/m4a download on a machine without AtomicParsley installed; or with an AtomicParsley that exists but is not executable/crashes on -v so check_executable fails.

Common situations: Fresh CI containers or minimal servers where only ffmpeg is installed; macOS Homebrew renaming (atomicparsley formula) leaving a non-executable binary; PATH not including the directory where AtomicParsley lives.

Related errors


AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14). Data as JSON: /api/errors/9e4a2d47d5398cce. Report an issue: GitHub.