HFValidationError
huggingface_hub.utils.HFValidationError
Stack trace
huggingface_hub.utils.HFValidationError: Token is invalid. It must be a user access token (not a system token or API token) with 'read' permissions on model repositories.
Or:
huggingface_hub.utils._headers.HFUserAgentError: 401 Client Error: Unauthorized for url: https://huggingface.co/pyannote/speaker-diarization/resolve/main/pytorch_model.bin
Or:
FileNotFoundError: Model pyannote/speaker-diarization-3.0 not found. You need to accept the model license at https://huggingface.co/pyannote/speaker-diarization-3.0 before using it.
Traceback (most recent call last):
File "<your_code>.py", line X, in <module>
diarize_model = whisperx.DiarizationPipeline(model_name="pyannote/speaker-diarization-3.0")
File "site-packages/whisperx/diarization.py", line 89, in __init__
self.model = Pipeline.from_pretrained(model_name, use_auth_token=use_auth_token)
File "site-packages/pyannote/audio/core/pipeline.py", line 198, in from_pretrained
model = torch.hub.load(...)
File "site-packages/huggingface_hub/hub_mixin.py", line 135, in from_pretrained
raise HFValidationError(f"Token is invalid...") Why it happens
WhisperX's diarization pipeline downloads pre-trained pyannote.audio models from HuggingFace Hub at runtime. These models require explicit user authentication because they have license agreements (research-only, non-commercial). WhisperX passes the HuggingFace token to pyannote, which validates it against HuggingFace's servers. The error occurs when: (1) no token is provided, (2) the token is invalid or expired, (3) the token lacks 'read' permissions, (4) the token's associated user hasn't accepted the model license, or (5) the token is a legacy 'API token' instead of a 'user access token' (deprecated in 2024).
Detection
Before deploying WhisperX with diarization, test the authentication locally with: `from whisperx.diarization import DiarizationPipeline; DiarizationPipeline(model_name='pyannote/speaker-diarization-3.0')` to catch token issues before production. Add debug logging: `import logging; logging.basicConfig(level=logging.DEBUG)` to see the exact HTTP 401 response from HuggingFace.
Causes & fixes
HuggingFace token not set in environment or passed to WhisperX
Set the HF_TOKEN environment variable: `export HF_TOKEN='hf_xxxxx'` before running, or pass it explicitly: `diarize_model = whisperx.DiarizationPipeline(model_name='pyannote/speaker-diarization-3.0', use_auth_token=os.environ['HF_TOKEN'])`
Using deprecated 'API token' instead of 'user access token' (HuggingFace deprecated API tokens in 2024)
Go to https://huggingface.co/settings/tokens, delete the old 'API token', create a new 'User Access Token' with 'Read' permissions, and use that token value instead
HuggingFace token is valid but user account hasn't accepted the pyannote model license
Visit https://huggingface.co/pyannote/speaker-diarization-3.0, log in with your HuggingFace account, accept the license agreement, then retry with your token
Token has insufficient permissions (missing 'read' scope or restricted to specific repos)
Create a new HuggingFace User Access Token with 'Read' permissions (no repo restrictions) at https://huggingface.co/settings/tokens: do NOT restrict it to specific repositories
Code: broken vs fixed
#!/usr/bin/env python3
import whisperx
import os
# BROKEN: no HuggingFace token provided, or token not in environment
audio_path = 'sample.mp3'
device = 'cuda'
batch_size = 16
# Load base model
model = whisperx.load_model('base', device=device)
# Transcribe
result = model.transcribe(audio_path, batch_size=batch_size)
# FAILS HERE with HFValidationError — no token passed to diarization
diarize_model = whisperx.DiarizationPipeline(
model_name='pyannote/speaker-diarization-3.0',
use_auth_token=None # ← BROKEN: None means no authentication
)
diarize_result = diarize_model(audio_path)
print(diarize_result) #!/usr/bin/env python3
import whisperx
import os
from huggingface_hub import login
# FIXED: Load HuggingFace token from environment
hf_token = os.environ.get('HF_TOKEN')
if not hf_token:
raise ValueError('HF_TOKEN environment variable not set. Create a token at https://huggingface.co/settings/tokens')
# Pre-authenticate with HuggingFace (ensures pyannote can download models)
login(token=hf_token, add_to_git_credential=False)
audio_path = 'sample.mp3'
device = 'cuda'
batch_size = 16
# Load base model
model = whisperx.load_model('base', device=device)
# Transcribe
result = model.transcribe(audio_path, batch_size=batch_size)
# FIXED: Pass token explicitly to diarization pipeline
diarize_model = whisperx.DiarizationPipeline(
model_name='pyannote/speaker-diarization-3.0',
use_auth_token=hf_token # ← FIXED: Token from environment
)
diarize_result = diarize_model(audio_path)
print('Diarization succeeded:', diarize_result) Workaround
If you cannot obtain a valid HuggingFace token immediately, skip speaker diarization in WhisperX and use an open-source diarization alternative that doesn't require authentication: (1) Use `pyannote-speaker-diarization` with the open-source 'speechbrain/spkrec-ecapa-voxceleb' model instead, or (2) transcribe with WhisperX's base model only, then use Silero Speaker Diarization (open-source, no token needed) as a separate step, or (3) temporarily disable diarization: `result = model.transcribe(audio_path, batch_size=batch_size); # skip diarization step` and add speaker labels manually via clustering.
Prevention
Use HuggingFace token management best practices: (1) Store tokens in `.env` files or secret managers (never hardcode), (2) use `huggingface_hub.login()` at application startup to validate the token early, (3) set token expiration reminders (HF tokens are permanent but policies change), (4) monitor HFValidationError exceptions at API boundaries and log token validation failures for alerting, (5) for production services, use HuggingFace 'fine-grained tokens' with minimal necessary scopes rather than full read-access tokens.